本項目實現接口自動化的技術選型:Python+Requests+Pytest+YAML+Allure ,主要是針對以前開發的一個接口項目來進行學習,經過 Python+Requests 來發送和處理HTTP協議的請求接口,使用 Pytest 做爲測試執行器,使用 YAML 來管理測試數據,使用 Allure 來生成測試報告。html
接口項目開發學習:
使用Flask開發簡單接口(1)--GET請求接口
使用Flask開發簡單接口(2)--POST請求接口
使用Flask開發簡單接口(3)--引入MySQL
使用Flask開發簡單接口(4)--藉助Redis實現token驗證
使用Flask開發簡單接口(5)--數據加密處理python
本項目在實現過程當中,把整個項目拆分紅請求方法封裝、HTTP接口封裝、關鍵字封裝、測試用例等模塊。git
首先利用Python把HTTP接口封裝成Python接口,接着把這些Python接口組裝成一個個的關鍵字,再把關鍵字組裝成測試用例,而測試數據則經過YAML文件進行統一管理,而後再經過Pytest測試執行器來運行這些腳本,並結合Allure輸出測試報告。github
固然,若是感興趣的話,還能夠再對接口自動化進行Jenkins持續集成。sql
GitHub項目源碼地址:https://github.com/wintests/pytestDemo數據庫
在 core/rest_client.py
文件中,對 Requests
庫下一些常見的請求方法進行了簡單封裝,以便調用起來更加方便。json
class RestClient(): def __init__(self, api_root_url): self.api_root_url = api_root_url self.session = requests.session() def get(self, url, **kwargs): return self.request(url, "GET", **kwargs) def post(self, url, data=None, json=None, **kwargs): return self.request(url, "POST", data, json, **kwargs) def put(self, url, data=None, **kwargs): return self.request(url, "PUT", data, **kwargs) def delete(self, url, **kwargs): return self.request(url, "DELETE", **kwargs) def patch(self, url, data=None, **kwargs): return self.request(url, "PATCH", data, **kwargs) def request(self, url, method, data=None, json=None, **kwargs): url = self.api_root_url + url headers = dict(**kwargs).get("headers") params = dict(**kwargs).get("params") files = dict(**kwargs).get("params") cookies = dict(**kwargs).get("params") self.request_log(url, method, data, json, params, headers, files, cookies) if method == "GET": return self.session.get(url, **kwargs) if method == "POST": return requests.post(url, data, json, **kwargs) if method == "PUT": if json: # PUT 和 PATCH 中沒有提供直接使用json參數的方法,所以須要用data來傳入 data = complexjson.dumps(json) return self.session.put(url, data, **kwargs) if method == "DELETE": return self.session.delete(url, **kwargs) if method == "PATCH": if json: data = complexjson.dumps(json) return self.session.patch(url, data, **kwargs)
在 api/user.py
文件中,將上面封裝好的HTTP接口,再次封裝爲不一樣的Python接口。不一樣的Python接口,會處理不一樣URL下的請求。api
class User(RestClient): def __init__(self, api_root_url, **kwargs): super(User, self).__init__(api_root_url, **kwargs) def list_all_users(self, **kwargs): return self.get("/users", **kwargs) def list_one_user(self, username, **kwargs): return self.get("/users/{}".format(username), **kwargs) def register(self, **kwargs): return self.post("/register", **kwargs) def login(self, **kwargs): return self.post("/login", **kwargs) def update(self, user_id, **kwargs): return self.put("/update/user/{}".format(user_id), **kwargs) def delete(self, name, **kwargs): return self.post("/delete/user/{}".format(name), **kwargs)
在 core/result_base.py
下,定義了一個空類 ResultBase
,該類主要用於自定義關鍵字返回結果。cookie
class ResultBase(): pass """ 自定義示例: result = ResultBase() result.success = False result.msg = res.json()["msg"] result.response = res """
在多流程的業務場景測試下,經過自定義指望保存的返回數據值,以便更好的進行斷言。session
關鍵字應該是具備必定業務意義的,在封裝關鍵字的時候,能夠經過調用多個Python接口來完成。在某些狀況下,好比測試一個充值接口的時候,在充值後可能須要調用查詢接口獲得最新帳戶餘額,來判斷查詢結果與預期結果是否一致,那麼能夠這樣來進行測試:
充值-查詢
的操做封裝爲一個關鍵字,在這個關鍵字中依次調用充值和查詢的接口,並能夠自定義關鍵字的返回結果。根據用例名分配測試數據
測試數據位於 data
文件夾下,在這裏使用 YAML
來管理測試數據,同時要求測試數據中第一層的名稱,須要與測試用例的方法名保持一致,如 test_get_all_user_info
、test_delete_user
。
test_get_all_user_info: # 指望結果,指望返回碼,指望返回信息 # except_result, except_code, except_msg - [True, 0, "查詢成功"] 省略 test_delete_user: # 刪除的用戶名,指望結果,指望返回碼,指望返回信息 # username, except_result, except_code, except_msg - ["測試test", True, 0, "刪除用戶信息成功"] - ["wintest3", False, 3006, "該用戶不容許刪除"]
這裏藉助 fixture
方法,咱們就可以經過 request.function.__name__
自動獲取到當前執行用例的函數名 testcase_name
,當咱們傳入測試數據 api_data
以後,接着即可以使用 api_data.get(testcase_name)
來獲取到對應用例的測試數據。
import pytest from testcases.conftest import api_data @pytest.fixture(scope="function") def testcase_data(request): testcase_name = request.function.__name__ return api_data.get(testcase_name)
數據準備和清理
在接口自動化中,爲了保證用例可穩定、重複地執行,咱們還須要有測試前置操做和後置操做,即數據準備和數據清理工做。
@pytest.fixture(scope="function") def delete_register_user(): """註冊用戶前,先刪除數據,用例執行以後,再次刪除以清理數據""" del_sql = base_data["init_sql"]["delete_register_user"] db.execute_db(del_sql) logger.info("註冊用戶操做:清理用戶--準備註冊新用戶") logger.info("執行前置SQL:{}".format(del_sql)) yield # 用於喚醒 teardown 操做 db.execute_db(del_sql) logger.info("註冊用戶操做:刪除註冊的用戶") logger.info("執行後置SQL:{}".format(del_sql))
在這裏,以用戶註冊用例爲例。對於前置操做,咱們應該準備一條刪除SQL,用於將數據庫中已存在的相同用戶刪除,對於後置操做,咱們應該再執行刪除SQL,確保該測試數據正常完成清理工做。
在測試用例中,咱們只須要在用例上傳入 fixture
的函數參數名 delete_register_user
,這樣就能夠調用 fixture
實現測試前置及後置操做。固然,也可使用pytest裝飾器 @pytest.mark.usefixtures()
來完成,如:
@pytest.mark.usefixtures("delete_register_user")
Allure用例描述
在這裏,咱們結合 Allure 來實現輸出測試報告,同時咱們可使用其裝飾器來添加一些用例描述並顯示到測試報告中,以便報告內容更加清晰、直觀、可讀。如使用 @allure.title()
自定義報告中顯示的用例標題,使用 @allure.description()
自定義用例的描述內容,使用 @allure.step()
可在報告中顯示操做步驟,使用 @allure.issue()
可在報告中顯示缺陷及其連接等。
@allure.step("步驟1 ==>> 註冊用戶") def step_1(username, password, telephone, sex, address): logger.info("步驟1 ==>> 註冊用戶 ==>> {}, {}, {}, {}, {}".format(username, password, telephone, sex, address)) @allure.severity(allure.severity_level.NORMAL) @allure.epic("針對單個接口的測試") @allure.feature("用戶註冊模塊") class TestUserRegister(): """用戶註冊""" @allure.story("用例--註冊用戶信息") @allure.description("該用例是針對獲取用戶註冊接口的測試") @allure.issue("https://www.cnblogs.com/wintest", name="點擊,跳轉到對應BUG的連接地址") @allure.testcase("https://www.cnblogs.com/wintest", name="點擊,跳轉到對應用例的連接地址") @allure.title( "測試數據:【 {username},{password},{telephone},{sex},{address},{except_result},{except_code},{except_msg}】") @pytest.mark.single @pytest.mark.parametrize("username, password, telephone, sex, address, except_result, except_code, except_msg", api_data["test_register_user"]) @pytest.mark.usefixtures("delete_register_user") def test_delete_user(self, login_fixture, username, except_result, except_code, except_msg): 省略
首先,下載項目源碼後,在根目錄下找到 requirements.txt
文件,而後經過 pip 工具安裝 requirements.txt 依賴,執行命令:
pip3 install -r requirements.txt
接着,修改 config/setting.ini
配置文件,在Windows環境下,安裝相應依賴以後,在命令行窗口執行命令:
pytest
注意:由於我這裏是針對本身的接口項目進行測試,若是想直接執行個人測試用例來查看效果,須要提早部署上面提到的接口項目。
在命令行執行命令:pytest
運行用例後,會獲得一個測試報告的原始文件,但這個時候還不能打開成HTML的報告,還須要在項目根目錄下,執行命令啓動 allure
服務:
# 須要提早配置allure環境,才能夠直接使用命令行 allure serve ./report
最終,能夠看到測試報告的效果圖以下: