前言
pytest的參數化(parametrize)可以實現只需維護測試數據,就能生成不同的測試用例目的。可以在參數化的時候加 ids 參數對每個用例說明使用場景。
最終我們希望在 allure 報告上能詳細的展示出每個用例的標題描述,這樣才能更直觀的知道每個用例是干什么的。
參數化parametrize
先看一個簡單的pytest參數化案例演示test_a.py
# test_a.py
import pytest
import allure
# 作者:上海-悠悠 QQ交流群:779429633
def login(username, password):
'''登錄'''
print("輸入賬號:%s" % username)
print("輸入密碼:%s" % password)
# 返回
return {"code": 0, "msg": "success!"}
# 測試數據
test_datas = [
({"username": "yoyo1", "password": "123456"}, "success!"),
({"username": "yoyo2", "password": "123456"}, "failed!"),
({"username": "yoyo3", "password": "123456"}, "success!"),
]
@allure.story("登錄用例")
@pytest.mark.parametrize("test_input,expected",
test_datas
)
def test_login(test_input, expected):
'''測試登錄用例'''
# 獲取函數返回結果
result = login(test_input["username"], test_input["password"])
# 斷言
assert result["msg"] == expected
cmd命令行運行用例
> pytest --alluredir ./report test_a.py
> allure serve ./report
生成報告
這樣生成的報告在用例列表里面並不能很友好的展示出每個用例的執行場景,只知道哪個用例報錯了。
於是需要對每個用例加上描述,加一個 ids 參數
ids 參數使用
在上面用例部分代碼里面加個 ids 參數,用於描述每個用例的運行場景。
# 作者:上海-悠悠 QQ交流群:779429633
@allure.story("登錄用例")
@pytest.mark.parametrize("test_input,expected",
test_datas,
ids=[
"輸入正確賬號,密碼,登錄成功",
"輸入錯誤賬號,密碼,登錄失敗",
"輸入正確賬號,密碼,登錄成功",
]
)
def test_login(test_input, expected):
'''測試登錄用例'''
# 獲取函數返回結果
result = login(test_input["username"], test_input["password"])
# 斷言
assert result["msg"] == expected
cmd命令行運行用例
> pytest --alluredir ./report test_a.py
> allure serve ./report
生成報告
allure.title描述用例
上面是通過在 parametrize 里面添加 ids 參數解決,接下來再講一個用 allure.title("用例描述") 添加用例描述的方式解決。
使用 @allure.title("用例描述") 時,可以加上傳入的參數,如傳入的參數 "test_input,expected"
,需拼接test_input參數的值,可以這樣寫
@allure.title("用例描述,測試輸入:{test_input}")
在 allure_pytest/utils.py 源碼里面可以找到對應的代碼
# allure_pytest/utils.py
def allure_name(item, parameters):
name = escape_name(item.name)
title = allure_title(item)
return title.format(**parameters) if title else name
當沒有加allure.title()時候,用例的描述就是 item.name 值(也就是上面的 ids 用例的名稱),
如果加了allure.title(),那么用例的描述就是添加的title值,這兩個地方取其中的一個。
import pytest
import allure
# 作者:上海-悠悠 QQ交流群:779429633
def login(username, password):
'''登錄'''
print("輸入賬號:%s" % username)
print("輸入密碼:%s" % password)
# 返回
return {"code": 0, "msg": "success!"}
# 測試數據
test_datas = [
({"username": "yoyo1", "password": "123456"}, "success!"),
({"username": "yoyo2", "password": "123456"}, "failed!"),
({"username": "yoyo3", "password": "123456"}, "success!"),
]
@allure.story("登錄用例")
@allure.title("用例描述,測試輸入:{test_input}")
@pytest.mark.parametrize("test_input,expected",
test_datas,
ids=[
"輸入正確賬號,密碼,登錄成功",
"輸入錯誤賬號,密碼,登錄失敗",
"輸入正確賬號,密碼,登錄成功",
]
)
def test_login(test_input, expected):
'''測試登錄用例'''
# 獲取函數返回結果
result = login(test_input["username"], test_input["password"])
# 斷言
assert result["msg"] == expected
cmd命令行運行用例
> pytest --alluredir ./report test_a.py
> allure serve ./report
生成報告
優化用例title
結合上面兩種實現方式,把用例描述當成一個測試輸入的參數,繼續優化后如下
需注意的是 parametrize 里面三個參數 test_input,expected,title
跟 test_login(test_input, expected, title) 里面三個參數保持一致
import pytest
import allure
# 作者:上海-悠悠 QQ交流群:779429633
def login(username, password):
'''登錄'''
print("輸入賬號:%s" % username)
print("輸入密碼:%s" % password)
# 返回
return {"code": 0, "msg": "success!"}
# 測試數據
test_datas = [
({"username": "yoyo1", "password": "123456"}, "success!", "輸入正確賬號,密碼,登錄成功"),
({"username": "yoyo2", "password": "123456"}, "failed!", "輸入錯誤賬號,密碼,登錄失敗"),
({"username": "yoyo3", "password": "123456"}, "success!", "輸入正確賬號,密碼,登錄成功"),
]
@allure.story("登錄用例")
@allure.title("{title}")
@pytest.mark.parametrize("test_input,expected,title",
test_datas
)
def test_login(test_input, expected, title):
'''測試登錄用例'''
# 獲取函數返回結果
result = login(test_input["username"], test_input["password"])
# 斷言
assert result["msg"] == expected