目錄
- 1、標記跳過
- (一)無條件跳過skip
- (二)有條件跳過skipif
- 2、標記實作引數化
- 示例1:單個引數
- 示例2:多個引數
- 示例3:多個引數化(笛卡爾積)
- 示例4:ids引數給用例起別名
- 示例5:使用indirect處理引數值
- 示例6:標記資料
1、標記跳過
在自動化測驗程序中,我們經常會遇到因為某些功能阻塞,未開發完成或者環境等問題,一些測驗用例不能執行,如果人工去注釋掉,后面還需要再恢復才能繼續測驗,pytest的標記跳過功能就可以實作暫時跳過,
(一)無條件跳過skip
使用方法:通過@pytest.mark.skip(reason=跳過原因)裝飾器標記要跳過的測驗用例
- 引數
reason:跳過的原因,非必填
import pytest
@pytest.mark.skip
def test_register():
# 測驗注冊功能
raise Exception("該功能尚未開發完成")
@pytest.mark.skip(reason="該功能尚未開發完成")
def test_logout():
# 注銷
raise Exception("該功能尚未開發完成")
def test_login():
# 登錄功能
assert True
"""
執行結果
mark/skip_mark.py::test_register SKIPPED (unconditional skip)
mark/skip_mark.py::test_logout SKIPPED (該功能尚未開發完成)
mark/skip_mark.py::test_login PASSED
"""
(二)有條件跳過skipif
使用方法:通過@pytest.mark.skipif(condition=跳過條件,reason=跳過原因)標記要跳過的測驗用例,
- 引數
condition:跳過的條件,值為True則跳過,值為False則繼續執行,默認值為True - 引數
reason:必填,跳過的原因
import pytest
version = 3.0
@pytest.mark.skipif(condition=version > 3.0 or version == 3.0, reason="3.0及以上版本不提供下載功能")
def test_download():
print("下載功能")
def test_upload():
print("上傳功能")
"""
執行結果
mark/skipif_mark.py::test_download SKIPPED (3.0及以上版本不提供下載功能)
mark/skipif_mark.py::test_upload 上傳功能
PASSED
"""
2、標記實作引數化
通過@pytest.mark.parametrize(argnames, argvalues, indirect=False, ids=None, scope=None)裝飾器來實作引數化,
引數說明:
argnames:引數名,使用逗號分隔的串列,或元祖,或字串,表示一個或多個引數名,【常用】argvalues:引數值,可以是串列、元祖、字典串列、字典元祖,【常用】indirect:中文翻譯為中間人,為True時可以對argvalues的引數值進行處理,默認False,【不常用】indirect=True: 且argnames的值為fixture函式名,此時argnames的值變為可執行函式,會將argvalues的引數值當做引數傳遞給fixture函式進行處理,fixture函式回傳處理結果給argnamesindirect=False:argnames僅為引數名
ids:給用例起別名,字串串列或數字串列,不設定會自動從測驗資料中提取scope:待理解【不常用】
示例1:單個引數
import pytest
phone_list = [
"13881118888",
"13012034288",
"13234324188",
"13231423288"
]
@pytest.mark.parametrize(argnames="phone_num", argvalues=phone_list)
def test_phone_number(phone_num): # 注意,這里的引數要和argnames引數名一致
print(f"正在測驗手機號{phone_num}")
"""
執行結果
mark/parametrize/single_param.py::test_phone_number[13881118888] 正在測驗手機號13881118888
PASSED
mark/parametrize/single_param.py::test_phone_number[13012034288] 正在測驗手機號13012034288
PASSED
mark/parametrize/single_param.py::test_phone_number[13234324188] 正在測驗手機號13234324188
PASSED
mark/parametrize/single_param.py::test_phone_number[13231423288] 正在測驗手機號13231423288
PASSED
"""
示例2:多個引數
import pytest
user_info = [
("張三", "18011111111"),
("李四", "18022222222"),
("王五", "18033333333")
]
@pytest.mark.parametrize(argnames="name,phonenum", argvalues=user_info)
def test_read_info(name, phonenum):
print(f"正在讀取用戶{name},手機號{phonenum}")
"""
執行結果
mark/parametrize/multiple_param.py::test_read_info[\u5f20\u4e09-18011111111] 正在讀取用戶張三,手機號18011111111
PASSED
mark/parametrize/multiple_param.py::test_read_info[\u674e\u56db-18022222222] 正在讀取用戶李四,手機號18022222222
PASSED
mark/parametrize/multiple_param.py::test_read_info[\u738b\u4e94-18033333333] 正在讀取用戶王五,手機號18033333333
PASSED
"""
由上面例子執行結果中可以看到中文引數值亂碼了,解決辦法如下
方法1. 在pytest.ini中加入disable_test_id_escaping_and_forfeit_all_rights_to_community_support=True
方法2. 在conftest.py中加入
# 收集每一個用例name和nodeid的中文顯示,轉化為utf-8形式
def pytest_collection_modifyitems(items):
for item in items:
item.name = item.name.encode("utf-8").decode("unicode_escape")
item._nodeid = item.nodeid.encode("utf-8").decode("unicode_escape")
示例3:多個引數化(笛卡爾積)
import pytest
data1 = ['a', 'b', 'c']
data2 = [1, 2]
@pytest.mark.parametrize('test1', data1)
@pytest.mark.parametrize('test2', data2)
def test_param(test1, test2):
print('\n測驗資料:{}-{}'.format(test1, test2))
"""
執行結果
mark/parametrize/multiple_parameterization.py::test_param[1-a]
測驗資料:a-1
PASSED
mark/parametrize/multiple_parameterization.py::test_param[1-b]
測驗資料:b-1
PASSED
mark/parametrize/multiple_parameterization.py::test_param[1-c]
測驗資料:c-1
PASSED
mark/parametrize/multiple_parameterization.py::test_param[2-a]
測驗資料:a-2
PASSED
mark/parametrize/multiple_parameterization.py::test_param[2-b]
測驗資料:b-2
PASSED
mark/parametrize/multiple_parameterization.py::test_param[2-c]
測驗資料:c-2
PASSED
"""
示例4:ids引數給用例起別名
import pytest
user_info = [
("張三", "18011111111"),
("李四", "18022222222"),
("王五", "18033333333")
]
@pytest.mark.parametrize(argnames="name,phonenum", argvalues=user_info, ids=["用戶1","用戶2","用戶3"])
def test_read_info(name, phonenum):
print(f"正在讀取用戶{name},手機號{phonenum}")
"""
執行結果
mark/parametrize/ids.py::test_read_info[用戶1] 正在讀取用戶張三,手機號18011111111
PASSED
mark/parametrize/ids.py::test_read_info[用戶2] 正在讀取用戶李四,手機號18022222222
PASSED
mark/parametrize/ids.py::test_read_info[用戶3] 正在讀取用戶王五,手機號18033333333
PASSED
"""
示例5:使用indirect處理引數值
import pytest
@pytest.fixture()
def fixture_and_parametrize(request): # request是關鍵字不能改變,用來接收引數
print('郵箱賬號為:{}'.format(request.param))
return request.param + "@qq.com"
@pytest.mark.parametrize('fixture_and_parametrize', ['100203', '466238894', '23942423'],
indirect=True)
def test_fixture_and_parametrize_2(fixture_and_parametrize):
print('拼接后郵箱為:{}'.format(fixture_and_parametrize))
"""
執行結果
mark/parametrize/indirect.py::test_fixture_and_parametrize_2[100203] 郵箱賬號為:100203
拼接后郵箱為:[email protected]
PASSED
mark/parametrize/indirect.py::test_fixture_and_parametrize_2[466238894] 郵箱賬號為:466238894
拼接后郵箱為:[email protected]
PASSED
mark/parametrize/indirect.py::test_fixture_and_parametrize_2[23942423] 郵箱賬號為:23942423
拼接后郵箱為:[email protected]
PASSED
"""
示例6:標記資料
在引數化的程序中也可以標記資料進行跳過等
import pytest
@pytest.mark.parametrize("test_input,expected", [
("3+9", 12), ("5+4", 9),
pytest.param("7 * 9", 42, marks=pytest.mark.xfail),
pytest.param("8 * 6", 42, marks=pytest.mark.skip)
])
def test_mark(test_input, expected):
assert eval(test_input) == expected
"""
執行結果
mark/parametrize/mark_data.py::test_mark[3+9-12] PASSED
mark/parametrize/mark_data.py::test_mark[5+4-9] PASSED
mark/parametrize/mark_data.py::test_mark[7 * 9-42] XFAIL
mark/parametrize/mark_data.py::test_mark[8 * 6-42] SKIPPED (unconditional skip)
"""
參考
https://www.cnblogs.com/miki-peng/p/14736332.html
https://zhuanlan.zhihu.com/p/515377205
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/502203.html
標籤:Python
上一篇:字串格式化
