能夠經過命令行查看全部marker,包括內置和自定義的python
pytest --markers
內置marker本文先講usefixtures 、filterwarnings 、skip 、skipif 、xfail這5個。參數化的marker我會寫在《pytest參數化》中,hook的marker我會寫在《pytest hook》中,插件的marker(pytest-ordering、allure等)我會寫在《pytest插件》中。當前只需知道有以上這些分類的marker便可,更多內容請關注後續文章。web
若是咱們只想把fixture注入到test中,test不直接訪問fixture的時候,就須要用到usefixtures。shell
示例,test須要一個臨時目錄,可是並不須要知道這個目錄具體路徑在哪windows
# content of conftest.py import os import shutil import tempfile import pytest @pytest.fixture def cleandir(): old_cwd = os.getcwd() newpath = tempfile.mkdtemp() os.chdir(newpath) yield os.chdir(old_cwd) shutil.rmtree(newpath)
# content of test_setenv.py import os import pytest @pytest.mark.usefixtures("cleandir") class TestDirectoryInit: def test_cwd_starts_empty(self): assert os.listdir(os.getcwd()) == [] with open("myfile", "w") as f: f.write("hello") def test_cwd_again_starts_empty(self): assert os.listdir(os.getcwd()) == []
TestDirectoryInit的測試方法須要一個臨時目錄做爲當前工做目錄,在類上添加@pytest.mark.usefixtures("cleandir")
,類的方法不加fixture也能有"cleandir"的效果。api
usefixtures能夠添加多個fixtureapp
@pytest.mark.usefixtures("cleandir", "anotherfixture")
usefixtures能夠用在pytestmark,做用域是定義所在module的全部tests函數
pytestmark = pytest.mark.usefixtures("cleandir")
usefixtures也能夠用在pytest.ini,做用域是整個項目的全部tests測試
# content of pytest.ini [pytest] usefixtures = cleandir
不過須要注意的是fixture函數自己是不能用usefixtures的,若是想要嵌套fixture,只能經過在fixture修飾的函數中,添加參數這種方式。ui
過濾警告信息。this
示例,api_v1()拋出了「api v1」的警告,test_one()函數使用filterwarnings過濾掉了
import warnings def api_v1(): warnings.warn(UserWarning("api v1, should use functions from v2")) return 1 @pytest.mark.filterwarnings("ignore:api v1") def test_one(): assert api_v1() == 1
一樣能夠添加到pytestmark和pytest.ini中。
跳過,不測試。
示例,skip須要添加reason哦
@pytest.mark.skip(reason="no way of currently testing this") def test_the_unknown(): ...
不過,更實用的方式是調用pytest.skip(reason)函數,而不是用mark,這樣就能夠用if判斷跳不跳
def test_function(): if not valid_config(): pytest.skip("unsupported configuration")
allow_module_level 能夠跳過整個module
import sys import pytest if not sys.platform.startswith("win"): pytest.skip("skipping windows-only tests", allow_module_level=True)
if判斷跳不跳,還能夠用skipif。
示例,若是Python版本小於3.6就跳過測試
import sys @pytest.mark.skipif(sys.version_info < (3, 6), reason="requires python3.6 or higher") def test_function(): ...
若是想在summary中看到reason,須要添加-rs參數。
能夠把skipif賦值給變量,而後直接引用變量,或者把變量import到其餘module中使用
# content of test_mymodule.py import mymodule minversion = pytest.mark.skipif( mymodule.__versioninfo__ < (1, 1), reason="at least mymodule-1.1 required" ) @minversion def test_function(): ...
# test_myothermodule.py from test_mymodule import minversion @minversion def test_anotherfunction(): ...
skipif添加到class上,會跳過類中全部方法。
可使用pytestmark跳過module內全部test
# test_module.py pytestmark = pytest.mark.skipif(...)
若是function有多個skipif做用,只要有一個爲True,就會跳過。
明知失敗,依然前行!很差意思跑偏了。xfail就是expected fail,預期失敗
@pytest.mark.xfail def test_function(): ...
執行後summary不會統計爲"failed",會單獨列出來。若是結果失敗了,「expected to fail」 (XFAIL);若是結果成功了,「unexpectedly passing」 (XPASS)。可是整個執行結果是」Tests passed「。
if判斷
def test_function(): if not valid_config(): pytest.xfail("failing configuration (but should work)")
值得注意的是,marker會繼續執行全部test代碼,pytest.xfail()函數會拋出異常,中斷執行後續代碼
添加condition,判斷條件
@pytest.mark.xfail(sys.platform == "win32", reason="bug in a 3rd party library") def test_function(): ...
添加reason,理由
@pytest.mark.xfail(reason="known parser issue") def test_function(): ...
添加raises,拋出異常/錯誤
@pytest.mark.xfail(raises=RuntimeError) def test_function(): ...
添加run,禁止運行
@pytest.mark.xfail(run=False) def test_function(): ...
添加strict,嚴格模式,即便xpass也會強制失敗,summary中有輸出信息」[XPASS(strict)] 「,測試結果爲」Tests failed「。
@pytest.mark.xfail(strict=True) def test_function(): ...
斷言成功也強制失敗,確實夠強勢的!
能夠在ini文件中定義全局strict
[pytest] xfail_strict=true
在命令行添加--runxfail,忽略xfail marker,至關於沒有添加這個標記的效果,該成功就成功,該失敗就失敗,再強勢也不虛,哈哈,惡靈退散。
pytest --runxfail
pytest --runxfail
再強勢也不虛,惡靈退散,哈哈。
經過註解自定義marker
# content of test_server.py import pytest @pytest.mark.webtest def test_send_http(): pass # perform some webtest test for your app def test_something_quick(): pass def test_another(): pass class TestClass: def test_method(self): pass
在命令行經過-m
指定運行mark打標的test
$ pytest -v -m webtest
也能夠反選
$ pytest -v -m "not webtest"
可是,這樣定義的marker是未註冊的!在執行後會警告,PytestUnknownMarkWarning。若是添加了命令行參數--strict-markers
,未註冊的marker會報錯。
能夠在pytest.ini文件中註冊,冒號後面的全部代碼都是marker說明,包括換行
[pytest] markers = slow: marks tests as slow (deselect with '-m "not slow"') serial
更高級的,能夠在pytest_configure hook函數中註冊,這主要用在第三方插件
def pytest_configure(config): config.addinivalue_line( "markers", "env(name): mark test to run only on named environment" )
本文介紹了5個pytest內置的marker,接着介紹瞭如何自定義marker和註冊marker。經過marker,可讓咱們更靈活的執行用例。
參考資料
docs-pytest-org-en-stable