1. 程式人生 > 實用技巧 >介面測試框架實戰 | 流程封裝與基於加密介面的測試用例設計

介面測試框架實戰 | 流程封裝與基於加密介面的測試用例設計

本文節選自霍格沃茲《測試開發實戰進階》課程教學內容。

介面測試僅僅掌握 Requests 或者其他一些功能強大的庫的用法,是遠遠不夠的,還需要具備能根據公司的業務流程以及需求去定製化一個介面自動化測試框架的能力。所以,接下來,我們主要介紹下介面測試用例分析以及通用的流程封裝是如何完成的。

介面測試用例分析

首先在做用例分析之前,可以通過追查公司一年來所有的故障原因,定位問題起因,或者通過與 CTO、產品經理、研發、運維、測試調查,得到質量痛點,還可以分析業務架構、流程呼叫,以及監控系統瞭解到業務的使用資料,從而得到質量需求。

得到質量需求之後,通過與產品經理、專案經理、研發總監等對接後得知待測業務範圍、業務場景用例、業務介面分析,從而確定公司的測試計劃。將測試計劃與質量需求結合進行分析,就可以開始進行業務用例的設計,而介面測試用例分析,也在其內。

質量需求樣例

測試痛點公司的介面一直不穩定影響使用者的使用質量反饋最近半年來出現了幾次大的故障迴歸測試每次升級都會影響老的功能測試策略目前公司沒有可靠的測試體系重構測試微服務話改造需要有良好的測試體系保證

介面測試封裝思想

介面封裝思想主要分為 3 個大維度:配置、介面封裝、業務流程。其中:

  • 配置主要用作根據配置檔案獲取初始配置和依賴;
  • 介面封裝遵循 APIObject 設計模式,對介面的呼叫進行抽象封裝;
  • 業務流程則負責資料初始化、業務用例設計,包含有多個 API 形成的流程定義,不要再包含任何介面實現細節、以及斷言。

下面將會與實戰案例結合,進行詳細的介紹。

基於加密介面的測試用例設計

由於資訊保安原因,許多介面在傳輸的時候會對請求與響應進行加密處理,如果直接對這部分資料做斷言顯然是行不通的。還需要對這部分介面額外進行解密的處理之後,才可以對已解密的介面進行斷言。

環境準備

在進行實戰之前,需要先準備一個對響應加密的介面。對它發起一個 get 請求後,得到一個加密過後的響應資訊。

先準備一個 JSON 格式 demo:

{"topics":
{
"orange":"movie",
"shool":"testing-studio",
"president":"seveniruby"
}
}

使用 base64 對其做加密,得到一個加密後的檔案 demo64.txt

base64demo.json>demo64.txt

使用 Python 命令在 “demo64.txt” 所在目錄啟動一個服務

python-mhttp.server10000

啟動後的樣子如圖:

使用curl命令對這個服務進行get請求:

curlhttp://127.0.0.1:10000/demo64.txt

如果請求成功的話就代表環境已經準備成功

實戰練習

呼叫 base64,直接對返回的請求做解密,即可得到解密後的響應,將解密後的響應轉為 JSON 格式,此時就可以對這個返回值做斷言且不會報錯了。

importbase64
importjson
importrequests
classTestEncode:
url="http://127.0.0.1:10000/demo64.txt"
deftest_encode(self):
r=requests.get(self.url)
encode=json.loads(base64.b64decode(r.content))
assertencode["topics"]["president"]=="seveniruby"

這樣的寫法顯然不夠優雅,如果被測介面的協議發生變化,Requests 庫無法支援改變後的協議,需要呼叫別的第三庫傳送請求資訊,則還是需要修改底層的原始碼。碰到這種情況,可以增加一層封裝,構造一層更加通用的傳送方法。

首先需要通過一個字典的結構體,儲存所有的請求資訊,包括髮送的協議、解碼方式、請求 method 等等,而這種字典形式的結構體也為後面的資料驅動改造做好了一個重要的鋪墊。

req_data={
"schema":"http",
"method":"get",
"url":"http://127.0.0.1:10000/demo64.txt",
"headers":None
}

通過請求資訊的結構體中的schema,新增判斷條件,去選擇不同的請求協議。舉個例子,如果 schema 為“http”的話,就選擇呼叫被封裝的 requests 庫。

classApiRequest:
#構造send方法,通過
defsend(self,data:dict):
if"http"==data["schema"]:
res=requests.request(data["method"],data["url"],header=data["headers"])
returnjson.loads(base64.decode(res.content))
elif"dubbo"==data["schema"]:
pass
elif"websocket"==data["schema"]:
pass
else:
pass

呼叫在ApiRequest類中的send方法傳送請求並進行斷言

classTestEncode:
deftest_api(self):
req_data={
"schema":"http",
"encoding":"base64",
"method":"get",
"url":"http://127.0.0.1:10000/demo64.txt",
"headers":None
}
re=ApiRequest()
data=re.send(req_data)
assertdata["topics"]["president"]=="seveniruby"

如果面對不同的演算法,還需要修改底層的原始碼,所以需要把演算法封裝。需要使用哪個演算法,就使用哪個。封裝的思想與上面相同。首先在字典結構體中新增一個 encoding 欄位,用來判斷選擇的不同的加密條件。

req_data={
"schema":"http",
"method":"get",
"url":"http://127.0.0.1:10000/demo64.txt",
"headers":None,
"encoding":"base64"
}

還是通過請求資訊的結構體中的 encoding,新增判斷條件,去選擇不同的解密方式。

classApiRequest:
defsend(self,data:dict):
if"http"==data["schema"]:
res=requests.request(data["method"],data["url"],headers=data["headers"])
returnjson.loads(base64.b64decode(res.content))
#通過請求資訊的結構體中的`encoding`,去選擇不同的解密方式。
ifdata["encoding"]=="base64":
returnjson.loads(base64.b64decode(res.content))
elifdata["encoding"]=="private":
returnjson.loads(requests.post("url",data=res.content).content)
else:
returnjson.loads(res.content)

總結

首先需要明確在面對一個加密的響應結果,可以使用什麼樣的處理方式:

  1. 如果知道使用的是哪個通用加密演算法的話,可以自行解決。
  2. 如果不瞭解對應的加密演算法的話,可以讓研發提供加解密的 lib。
  3. 如果既不是通用加密演算法、研發也無法提供加解密的 lib 的話,可以讓加密方提供遠端解析服務,這樣演算法仍然是保密的。

本文主要講的是在瞭解使用加密演算法的情況下,如何處理這樣的解密演算法。但是封裝的思路都是相通的,不管是面對哪種情況,都可以通過格式化的資料,指明資料的內容,並通過一層邏輯的封裝,將加解密或者選擇的協議封裝進去。

想關注更多內容,可關注公眾號:霍格沃茲測試學院