Tep集成 HttpRunner 與 Flask 實(shí)現(xiàn)開(kāi)箱即用
大家好,我是剛哥。
趁著元旦假期最后一天,有著大把時(shí)間,奔著把tep做大做強(qiáng)的目標(biāo),好好學(xué)習(xí)了一波。在開(kāi)始正文之前,先回答可能會(huì)問(wèn)到的兩個(gè)問(wèn)題。第一個(gè)問(wèn)題是為什么要集成HttpRunner?因?yàn)槲易罱谒伎既绾谓otep做分層設(shè)計(jì),參考了我司現(xiàn)有的接口自動(dòng)化平臺(tái),它的設(shè)計(jì)是每個(gè)用例有很多測(cè)試步驟,可以針對(duì)用例設(shè)置預(yù)設(shè)變量,然后在測(cè)試步驟中引用。正當(dāng)我準(zhǔn)備自己開(kāi)發(fā)類似功能時(shí),想到了HttpRunner,我記得HttpRunner第3版是建議直接編寫(xiě)pytest代碼而非以前的ymal或json文件了。大有所獲,HttpRunner正是以這種方式編寫(xiě)的代碼,而且和pytest有很好的結(jié)合,很符合tep要集成的第三方包的希望。第二個(gè)問(wèn)題是為什么要集成Flask?剛開(kāi)始只是我用來(lái)調(diào)試代碼的,等到把Mock寫(xiě)完以后,想到可能大家也需要調(diào)試代碼,就把它做到tep里面了,并且附帶了測(cè)試用例的示例代碼,安裝完以后就能一鍵運(yùn)行,開(kāi)箱即用,美滋滋。歸根結(jié)底,都是為了把tep做大做強(qiáng)。
tep0.9.3正式發(fā)布
要體驗(yàn)HttpRunner和Flask,需要先安裝或升級(jí)到tep0.9.3。
安裝:
- pip install tep
升級(jí):
- pip install -U tep
或者指定版本:
- pip install tep==0.9.3
安裝tep時(shí)會(huì)順帶安裝HttpRunner和Flask,安裝完以后就可以執(zhí)行命令初始化項(xiàng)目:
- tep startproject demo093
輸出:
- D:\PycharmProjects>tep startproject demo093
- 2022-01-03 16:07:31.929 | INFO | tep.scaffold:create_scaffold:53 - Create new project: demo093
- Project root dir: D:\PycharmProjects\demo093
- Created folder: demo093
- Created folder: demo093\fixtures
- Created folder: demo093\tests
- Created folder: demo093\files
- Created folder: demo093\reports
- Created folder: demo093\utils
- Created file: demo093\.gitignore
- Created file: demo093\conf.yaml
- Created file: demo093\conftest.py
- Created file: demo093\pytest.ini
- Created file: demo093\fixtures\__init__.py
- Created file: demo093\fixtures\fixture_admin.py
- Created file: demo093\fixtures\fixture_env_vars.py
- Created file: demo093\fixtures\fixture_login.py
- Created file: demo093\fixtures\fixture_your_name.py
- Created file: demo093\tests\__init__.py
- Created file: demo093\tests\test_login.py
- Created file: demo093\tests\test_post.py
- Created file: demo093\tests\test_mysql.py
- Created file: demo093\tests\test_request.py
- Created file: demo093\tests\test_login_pay.py
- Created file: demo093\tests\test_login_pay_httprunner.py
- Created file: demo093\utils\__init__.py
- Created file: demo093\utils\flask_mock_api.py
- 修改了fixture_env_vars.py里面的domain為http://127.0.0.1:5000,這是Flask啟動(dòng)后的默認(rèn)地址。
- 修改了fixture_login.py里面的登錄url和username,跟Flask的Mock對(duì)應(yīng)。
- 新增了utils\flask_mock_api.py,直接啟動(dòng)Mock服務(wù)。
- 新增了tests\test_login_pay.py,用例數(shù)據(jù)一體開(kāi)發(fā)模式,登錄到下單流程的示例代碼,可以一鍵運(yùn)行成功。
- 新增了tests\test_login_pay_httprunner.py,HttpRunner開(kāi)發(fā)模式,登錄到下單流程的示例代碼,可以一鍵運(yùn)行成功。
新版README.md
之前tep的README是全英文的,這次我也決定不裝了,改成中文 ,豐富了內(nèi)容,大家可以對(duì)tep有個(gè)全新和全面的了解啦。以下是全文:
tep
tep是Try Easy Pytest的首字母縮寫(xiě),是一款基于pytest測(cè)試框架的測(cè)試工具,集成了各種實(shí)用的第三方包和優(yōu)秀的自動(dòng)化測(cè)試設(shè)計(jì)思想,幫你快速實(shí)現(xiàn)自動(dòng)化項(xiàng)目落地。
安裝
支持Python3.6以上,推薦Python3.8以上。
標(biāo)準(zhǔn)安裝:
- $ pip install tep
國(guó)內(nèi)鏡像:
- $ pip --default-timeout=600 install -i https://pypi.tuna.tsinghua.edu.cn/simple tep
檢查安裝成功:
- $ tep -V # 或者 tep --version
- 0.2.3
快速創(chuàng)建項(xiàng)目
tep提供了腳手架,預(yù)置了項(xiàng)目結(jié)構(gòu)和代碼,打開(kāi)cmd,使用startproject命令快速創(chuàng)建項(xiàng)目:
- tep startproject project_name
并且提供了-venv參數(shù),在項(xiàng)目初始化時(shí),可以同時(shí)創(chuàng)建一個(gè)虛擬環(huán)境(推薦):
- tep startproject project_name -venv
輸出測(cè)試報(bào)告
tep提供了--tep-reports參數(shù)來(lái)生成allure測(cè)試報(bào)告:
- pytest --tep-reports
報(bào)告文件存放在根目錄的reports/中。
Mock服務(wù)
tep自帶了一個(gè)Flask應(yīng)用(utils/flask_mock_api.py),提供了登錄到下單流程的5個(gè)接口,啟動(dòng)后即可一鍵運(yùn)行示例中的測(cè)試用例。
三種開(kāi)發(fā)模式
tep兼容三種開(kāi)發(fā)模式:用例數(shù)據(jù)一體(適合新手)、用例數(shù)據(jù)分離(適合老手)、HttpRunner(新老皆宜)。
①用例數(shù)據(jù)一體,示例代碼如下所示:
- def test(env_vars, login):
- # 搜索商品
- response = request(
- "get",
- url=env_vars.domain + "/searchSku",
- headers={"token": login.token},
- params={"skuName": "電子書(shū)"}
- )
- sku_id = jmespath.search("skuId", response.json())
- sku_price = jmespath.search("price", response.json())
- assert response.status_code < 400
- # 添加購(gòu)物車(chē)
- sku_num = 3
- response = request(
- "post",
- url=env_vars.domain + "/addCart",
- headers={"token": login.token},
- json={"skuId": sku_id, "skuNum": sku_num}
- )
- total_price = jmespath.search("totalPrice", response.json())
- assert response.status_code < 400
- # 下單
- response = request(
- "post",
- url=env_vars.domain + "/order",
- headers={"token": login.token},
- json={"skuId": sku_id, "price": sku_price, "skuNum": sku_num, "totalPrice": total_price}
- )
- order_id = jmespath.search("orderId", response.json())
- assert response.status_code < 400
- # 支付
- response = request(
- "post",
- url=env_vars.domain + "/pay",
- headers={"token": login.token},
- json={"orderId": order_id, "payAmount": "6.9"}
- )
- assert response.status_code < 400
- assert response.json()["success"] == "true"
更多內(nèi)容請(qǐng)參考《如何使用teprunner測(cè)試平臺(tái)編寫(xiě)從登錄到下單的大流程接口自動(dòng)化用例》
②用例數(shù)據(jù)分離
開(kāi)發(fā)中,敬請(qǐng)期待...
③HttpRunner,示例代碼如下所示:
- from httprunner import HttpRunner, Config, Step, RunRequest
- class TestLoginPay(HttpRunner):
- config = (
- Config("登錄到下單流程")
- .variables(
- **{
- "skuNum": "3"
- }
- )
- .base_url("http://127.0.0.1:5000")
- )
- teststeps = [
- Step(
- RunRequest("登錄")
- .post("/login")
- .with_headers(**{"Content-Type": "application/json"})
- .with_json({"username": "dongfanger", "password": "123456"})
- .extract()
- .with_jmespath("body.token", "token")
- .validate()
- .assert_equal("status_code", 200)
- ),
- Step(
- RunRequest("搜索商品")
- .get("searchSku?skuName=電子書(shū)")
- .with_headers(**{"token": "$token"})
- .extract()
- .with_jmespath("body.skuId", "skuId")
- .with_jmespath("body.price", "skuPrice")
- .validate()
- .assert_equal("status_code", 200)
- ),
- Step(
- RunRequest("添加購(gòu)物車(chē)")
- .post("/addCart")
- .with_headers(**{"Content-Type": "application/json",
- "token": "$token"})
- .with_json({"skuId": "$skuId", "skuNum": "$skuNum"})
- .extract()
- .with_jmespath("body.totalPrice", "totalPrice")
- .validate()
- .assert_equal("status_code", 200)
- ),
- Step(
- RunRequest("下單")
- .post("/order")
- .with_headers(**{"Content-Type": "application/json",
- "token": "$token"})
- .with_json({"skuId": "$skuId", "price": "$skuPrice", "skuNum": "$skuNum", "totalPrice": "$totalPrice"})
- .extract()
- .with_jmespath("body.orderId", "orderId")
- .validate()
- .assert_equal("status_code", 200)
- ),
- Step(
- RunRequest("支付")
- .post("/pay")
- .with_headers(**{"Content-Type": "application/json",
- "token": "$token"})
- .with_json({"orderId": "$orderId", "payAmount": "6.9"})
- .validate()
- .assert_equal("status_code", 200)
- .assert_equal("body.success", "true")
- ),
- ]
用戶手冊(cè)
https://dongfanger.gitee.io/blog/chapters/tep.html