🍅 點擊文末小卡片,免費獲取軟件測試全套資料,資料在手,漲薪更快
自動化本身是為了提高工作效率,不論選擇何種框架,何種開發語言,我們最終想實現的效果,就是讓大家用最少的代碼,最小的投入,完成自動化測試的工作。
基于這個想法,我們的接口自動化測試思路如下:
1.不變的內容全部通過配置化來實現,比如:腳本執行的環境、請求的 HOST、URL 路徑、測試數據等;
2.環境和數據關聯變更:依據不同的環境,選擇不同的配置及對應的測試數據;
3.抽取公共方法,避免冗余代碼;
4.場景化的用例,實現可配置化;
5.數據驅動。
一、問題
在做自動化的過程中,不能只考慮單接口的腳本,也要考慮場景化的用例。場景化的用例?不需要每個步驟都去校驗所有的數據,可能?更多看重串聯后的最終效果。
那什么是場景用例?
其實就是多個接口組成的業務場景,常規寫代碼的做法是,先調用接口1,驗證結果, 再調用接口2,再繼續接口3,… 等等;在測試場景中,可能只是各個接口的入參不一樣,或者是調用的接口不一樣。這樣代碼寫起來就會冗余。
比如:
def test_01(self):# step 01result1 = PackDemo().getTest()assert result1 == 4# step02result2 = PackDemo2().getTest2("name")assert result2 == 'name'# step03result3 = DemoApi().getTest()assert result3 == 2
這樣的用例,對于簡單的接口沒什么問題,但是對于復雜的接口,校驗邏輯比較多,或者入參比較多,實現的方式就過于單一了。且不同場景的話,每個都要更改調用的步驟和返回值,場景越多冗余越多。
如果使用配置化的方式,每次從配置文件中動態加載配置的場景用例, 而且能夠做到加載后做對應的斷言,那該多好。
怎么做呢?咱們看看一些核心的實現。
二、方案
2.1 項目結構
項目結構如下:
img
采用當前比較流行的 Python + Pytest + Allure 來實現,具體結構不做展開。
2.2 場景用例的配置數據
test_scenario.json
{"test_01": {"step_1": { ---- 步驟節點名稱,可自定義"packagePath": "api", --- 這個步驟要運行的方法所屬類的包路徑"class": "DemoApi", --- 這個步驟要運行的方法所屬類名稱"method": "getTest", --- 這個步驟要運行的方法名稱"request": null, ---這個步驟運行的方法入參"response": 2, ---這個步驟運行的結果,可以是一個值,或者對象"verify": { --- 數據校驗的節點"type": 1, ---數據校驗的類型"keys": null ---如果是校驗的特定字段,這里需要輸入部分校驗的字段}},"step_2": {"packagePath": "api.demo","class": "PackDemo","method": "getTest2","request": "request -> name","response": 6,"verify": {"type": 1,"keys": null}},"step_3": {"packagePath": "api.demo","class": "PackDemo2","method": "getTest3","request": {"name": "param-name","num_list": ["a", "b", "c"]},"response": 8,"verify": {"type": 1,"keys": null}}}
}
2.3 動態加載類
在我們配置了以上的測試場景的數據后,我們希望在用例執行的過程中,通過獲取我們的配置,能夠動態的加載數據文件中提到的方法,并執行對應的方法,那這個過程的實現我們主要通過如下的動態加載類來實現。
# DynamicLoad.py
# 部分主要的摘錄如下def __load_module(self):"""加載對應路徑下的模塊:param package_path: 包路徑:param class_name: 類名稱:return:"""return importlib.import_module("." + self.class_name, package=self.package_path)def __getClassInstance(self):"""加載對應的模塊下的類,并返回對應類的實例 :param module_name: 對應的模塊:param class_name::return:"""self.my_module = self.__load_module()self.my_class = getattr(self.my_module, self.class_name)()return self.my_classdef execMethod(self, method, *args):"""加載對應類下的方法 :param instance: 對應的實例:param method: 要執行的方法:return:"""result = getattr(self.__getClassInstance(), method)(*args)return result
有了以上動態加載的方法后,在執行場景用例時,依據上述的方法,就可以執行測試文件中提到的方法。
2.4 場景分析類
在場景用例的測試數據中,除了需要解析需要執行的類、方法外,還要解析文件中涉及到的出入參及數據比對方式,因此,這里還需要一個場景分析類,來解析數據文件中關于具體執行過程的配置。
#ScenariosAnalyze.pydef analyse_exe_scenario(self, case_data):step_result = {}summary = Truefor i in case_data:instance = DynamicLoad(case_data[i]['packagePath'], case_data[i]['class'])if case_data[i]['request'] is not None:result = instance.execMethod(case_data[i]['method'], case_data[i]['request'])else:result = instance.execMethod(case_data[i]['method'])if case_data[i]['verify'] is not None:compare_type = case_data[i]['verify']['type']keys = case_data[i]['verify']['keys']step_compare_result = DataCompare().compare_type(compare_type=compare_type, actual=result,expect=case_data[i]['response'], keys=keys)if not step_compare_result:summary = Falsestep_result[i] = step_compare_resultstep_result['summary'] = summaryreturn step_result
2.5 用例實現
@File : test_scenario.pyclass TestScenario:@allure.story('場景用例01')@allure.severity(allure.severity_level.BLOCKER)@pytest.mark.smokedef test_01(self):result = Nonecase_data = self.test_data_json['test_01']result = self.scenario_analyze.analyse_exe_scenario(case_data)assert result['summary'] is True
通過上述簡單的腳本調用,就可以完成一個場景用例的測試了。
三、小結
以上就是場景用例配置化的實現思路。
它的優點是:
1.配置化: 一切固定不變的內容全部配置化,最終達到:一個環境配置文件,一套腳本,幾套測試數據,依據環境的不同選擇不同的測試數據執行對應的測試腳本;
2.門檻低:因為配置化,測試同學只要把測試數據文件中的關鍵節點配置好,然后在腳本中寫下調用方法,就完成用例編寫了;
3.好擴展:在后續的實現中,可以將這些配置全部頁面化,包括環境、數據、腳本,達到無代碼開發的目的;
缺點當然是不夠靈活,所以沒有完美的方案,只有合適的,以上,僅供大家參考。
最后感謝每一個認真閱讀我文章的人,禮尚往來總是要有的,雖然不是什么很值錢的東西,如果你用得到的話可以直接拿走:
這些資料,對于做【軟件測試】的朋友來說應該是最全面最完整的備戰倉庫,這個倉庫也陪伴我走過了最艱難的路程,希望也能幫助到你!凡事要趁早,特別是技術行業,一定要提升技術功底。