目錄:
- 安裝及入門
- 使用和調(diào)用方法
- 原有TestSuite使用方法
- 斷言的編寫(xiě)和報(bào)告
- Pytest fixtures:清晰 模塊化 易擴(kuò)展
- 使用Marks標(biāo)記測(cè)試用例
- Monkeypatching/對(duì)模塊和環(huán)境進(jìn)行Mock
- 使用tmp目錄和文件
- 捕獲stdout及stderr輸出
- 捕獲警告信息
- 模塊及測(cè)試文件中集成doctest測(cè)試
- skip及xfail: 處理不能成功的測(cè)試用例
- Fixture方法及測(cè)試用例的參數(shù)化
- 緩存: 使用跨執(zhí)行狀態(tài)
- unittest.TestCase支持
- 運(yùn)行Nose用例
- 經(jīng)典xUnit風(fēng)格的setup/teardown
- 安裝和使用插件
- 插件編寫(xiě)
- 編寫(xiě)鉤子(hook)方法
- 運(yùn)行日志
- API參考
- 優(yōu)質(zhì)集成實(shí)踐
- 片狀測(cè)試
- Pytest導(dǎo)入機(jī)制及sys.path/PYTHONPATH
- 配置選項(xiàng)
- 示例及自定義技巧
- Bash自動(dòng)補(bǔ)全設(shè)置
使用Marks標(biāo)記測(cè)試用例
通過(guò)使用pytest.mark
你可以輕松地在測(cè)試方法上設(shè)置元數(shù)據(jù)肩榕。例如饼疙, 一些常用的內(nèi)置標(biāo)記:
- skip - 始終跳過(guò)該測(cè)試方法
- skipif - 遇到特定情況跳過(guò)該測(cè)試方法
- xfail - 遇到特定情況耘婚,產(chǎn)生一個(gè)“期望失敗”輸出
- parametrize - 在同一個(gè)測(cè)試方法上運(yùn)行多次調(diào)用
創(chuàng)建自定義標(biāo)記或?qū)?biāo)記應(yīng)用于整個(gè)測(cè)試類或模塊很容易啦吧。 文檔中包含有關(guān)標(biāo)記的示例窑滞,詳情可參閱使用自定義標(biāo)記。
注意:
標(biāo)記只對(duì)測(cè)試方法有效验懊,對(duì)fixtures方法無(wú)效卧惜。
在未知標(biāo)記上引發(fā)異常: -strict
當(dāng)使用--strict
命令行參數(shù)時(shí),未在pytest.ini
文件中注冊(cè)的任何標(biāo)記都將引發(fā)異常忿等。
標(biāo)記可以通過(guò)以下方式注冊(cè):
[pytest]
markers =
slow
serial
這可用于防止用戶意外輸錯(cuò)標(biāo)記名稱栖忠。 想要強(qiáng)制執(zhí)行此操作的測(cè)試套件應(yīng)將--strict
添加到addopts
:
[pytest]
addopts = --strict
markers =
slow
serial
標(biāo)記改造和迭代
3.6版本新功能
pytest的標(biāo)記傳統(tǒng)地實(shí)現(xiàn)是通過(guò)簡(jiǎn)單地在測(cè)試函數(shù)的__dict__
中添加屬性來(lái)進(jìn)行標(biāo)記。結(jié)果贸街,標(biāo)記意外的隨著類的集成而傳遞庵寞。此外,使用@pytest.mark
裝飾器應(yīng)用的標(biāo)記和通過(guò)node.add_marker
添加的標(biāo)記存儲(chǔ)的位置不同薛匪,用于檢索它們的API也
不一致捐川。
這樣,如果不深入了解測(cè)試代碼內(nèi)部結(jié)構(gòu)逸尖,技術(shù)上幾乎無(wú)法正確使用參數(shù)化數(shù)據(jù)古沥,從而導(dǎo)致在高級(jí)的用法中出現(xiàn)細(xì)微且難以理解的bug品腹。
根據(jù)標(biāo)記聲明/更改的方式致讥,你都可以獲得一個(gè)MarkerInfo
對(duì)象,其中也可能會(huì)包含來(lái)自同級(jí)類的標(biāo)記寓免。當(dāng)使用參數(shù)化標(biāo)記苞俘,或node.add_marker
時(shí)盹沈,會(huì)丟棄之前的使用裝飾器聲明的MarkDecorators
標(biāo)記。MarkerInfo
對(duì)象實(shí)際上是使用同一標(biāo)記名的多個(gè)標(biāo)記的合并視圖吃谣,當(dāng)然乞封,MarkerInfo
也可以像單個(gè)標(biāo)記一樣使用。
最重要的是基协,即使標(biāo)記是在類/模塊上聲明的歌亲,實(shí)際上菇用,標(biāo)記只能在函數(shù)中訪問(wèn)澜驮。原因是模塊,類和函數(shù)/方法無(wú)法以相同的方式訪問(wèn)標(biāo)記惋鸥。
在pytest 3.6版本中引入了一個(gè)訪問(wèn)標(biāo)記的新API杂穷,以解決初始設(shè)計(jì)中的問(wèn)題悍缠,提供_pytest.nodes.Node.iter_markers()方法以一致的方式迭代標(biāo)記并重新進(jìn)行內(nèi)部處理,這很好地解決了初始設(shè)計(jì)的問(wèn)題耐量。
升級(jí)代碼
不推薦使用原有的Node.get_marker(name)
函數(shù)飞蚓,因?yàn)樗祷匾粋€(gè)內(nèi)部MarkerInfo
對(duì)象,該對(duì)象包含應(yīng)用于該節(jié)點(diǎn)的所有標(biāo)記的合并名稱和所有參數(shù)廊蜒。
通常趴拧,有兩種方案可以處理標(biāo)記:
- 標(biāo)記互相覆蓋。 順序很重要山叮,但你只需要將你的標(biāo)記視為單獨(dú)的標(biāo)記即可著榴。 例如。 對(duì)于測(cè)試方法中的
log_level('debug')
會(huì)覆蓋模塊級(jí)別的log_level('info')
屁倔。
在這種情況下脑又,可以使用Node.get_closest_marker(name)
:
# 替換這個(gè):
marker = item.get_marker("log_level")
if marker:
level = marker.args[0]
# 通過(guò)這個(gè):
marker = item.get_closest_marker("log_level")
if marker:
level = marker.args[0]
- 在特定條件下使用標(biāo)記。 例如锐借,
skipif(condition)
標(biāo)記问麸,意味著你只想測(cè)試所有非condition條件的用例,順序不重要钞翔。你可以將這個(gè)標(biāo)記視為一個(gè)滿足該條件的集合使用严卖。
在這種情況下,迭代每個(gè)標(biāo)記并單獨(dú)處理它們的*args
和**kwargs
參數(shù)嗅战。
# 替換這個(gè):
skipif = item.get_marker("skipif")
if skipif:
for condition in skipif.args:
# eval condition
...
# 通過(guò)這個(gè):
for skipif in item.iter_markers("skipif"):
condition = skipif.args[0]
# eval condition
如果您不確定或遇到任何難題妄田,你可以考慮提出一個(gè)待解決問(wèn)題。
相關(guān)問(wèn)題
以下是新修復(fù)問(wèn)題的詳細(xì)列表:
- 標(biāo)記不會(huì)選擇嵌套類(#199)驮捍。
- 標(biāo)記在所有相關(guān)類別上染色(#568)疟呐。
- 組合標(biāo)記 - args和kwargs計(jì)算(#2897)。
- request.node.get_marker('name')為類中應(yīng)用的標(biāo)記返回None(#902)东且。
- 在參數(shù)化中應(yīng)用的標(biāo)記存儲(chǔ)為markdecorator(#2400)启具。
- 以向后不兼容的方式修復(fù)標(biāo)記交互(#1670)。
- 重構(gòu)標(biāo)記以擺脫當(dāng)前的“標(biāo)記轉(zhuǎn)移”機(jī)制(#2363)珊泳。
- 介紹FunctionDefinition節(jié)點(diǎn)鲁冯,在generate_tests中使用它(#2522)。
- 刪除命名標(biāo)記屬性并收集項(xiàng)目中的標(biāo)記(#891)色查。
- 來(lái)自參數(shù)化的跳過(guò)標(biāo)記隱藏模塊級(jí)跳過(guò)標(biāo)記(#1540)薯演。
- skipif + parametrize不跳過(guò)測(cè)試(#1296)。
- 標(biāo)記轉(zhuǎn)移與繼承不兼容(#535)秧了。
注意:
在未來(lái)的pytest主要版本中跨扮,我們將引入基于類的標(biāo)記,在這些標(biāo)記處,標(biāo)記將不再局限于Mark的實(shí)例衡创。