[英]Does pytest support “default” markers?
我正在使用pytest來測試嵌入式系統的python模型。 要測試的功能因平台而異。 (我在這個上下文中使用'platform'來表示嵌入式系統類型,而不是OS類型)。
組織我的測試最直接的方法是根據平台類型將它們分配給目錄。
/platform1
/platform2
/etc.
pytest / platform1
由於許多功能在不同平台上重疊,因此很快就難以支持。 我已經將我的測試移動到一個目錄中,每個功能區域的測試分配給一個文件名(例如test_functionalityA.py)。 然后我使用pytest標記來指示文件中的哪些測試適用於給定平台。
@pytest.mark.all_platforms
def test_some_functionalityA1():
...
@pytest.mark.platform1
@pytest.mark.platform2
def test_some_functionlityA2():
...
雖然我很樂意讓'conftest'自動檢測平台類型並且只運行相應的測試,但我已經決定在命令行上指定要運行的測試。
pytest -m“(platform1或all_platforms)”
問題:(終於!)
有沒有辦法簡化事情並讓pytest默認運行所有未標記的測試,另外所有測試都通過命令行上的'-m'傳遞?
例如:pytest -m“platform1”
會運行標記@ pytest.mark.platform1的測試以及所有標記為@ pytest.mark.all_platforms的測試,甚至所有測試都沒有@ pytest.mark嗎?
鑒於大量共享功能,能夠刪除@ pytest.mark.all_platforms行將是一個很大的幫助。
讓我們解決完整的問題。 我認為你可以把一個conftest.py文件和你的測試放在一起,它會注意跳過所有不匹配的測試(非標記的測試總是匹配,因此永遠不會被跳過)。 這里我使用的是sys.platform,但我相信你有不同的方法來計算你的平台價值。
# content of conftest.py
#
import sys
import pytest
ALL = set("osx linux2 win32".split())
def pytest_runtest_setup(item):
if isinstance(item, item.Function):
plat = sys.platform
if not hasattr(item.obj, plat):
if ALL.intersection(set(item.obj.__dict__)):
pytest.skip("cannot run on platform %s" %(plat))
有了它,你可以像這樣標記你的測試::
# content of test_plat.py
import pytest
@pytest.mark.osx
def test_if_apple_is_evil():
pass
@pytest.mark.linux2
def test_if_linux_works():
pass
@pytest.mark.win32
def test_if_win32_crashes():
pass
def test_runs_everywhere_yay():
pass
如果你運行::
$ py.test -rs
然后你可以運行它,並會看到至少兩個測試被跳過,並且總是至少執行一次測試::
然后你會看到兩個測試跳過和兩個執行測試按預期::
$ py.test -rs # this option reports skip reasons
=========================== test session starts ============================
platform linux2 -- Python 2.7.3 -- pytest-2.2.5.dev1
collecting ... collected 4 items
test_plat.py s.s.
========================= short test summary info ==========================
SKIP [2] /home/hpk/tmp/doc-exec-222/conftest.py:12: cannot run on platform linux2
=================== 2 passed, 2 skipped in 0.01 seconds ====================
請注意,如果您通過marker-command line選項指定平台,例如::
$ py.test -m linux2
=========================== test session starts ============================
platform linux2 -- Python 2.7.3 -- pytest-2.2.5.dev1
collecting ... collected 4 items
test_plat.py .
=================== 3 tests deselected by "-m 'linux2'" ====================
================== 1 passed, 3 deselected in 0.01 seconds ==================
那么未標記的測試將不會運行。 因此,這是一種將運行限制為特定測試的方法。
晚了,但我剛剛通過為所有未標記的測試添加默認標記解決了類似的問題。
作為問題的直接答案:您可以始終運行未標記的測試,並且僅通過-m
選項指定標記的測試,方法是將以下內容添加到conftest.py中
def pytest_collection_modifyitems(items, config):
# add `always_run` marker to all unmarked items
for item in items:
if not any(item.iter_markers()):
item.add_marker("always_run")
# Ensure the `always_run` marker is always selected for
markexpr = config.getoption("markexpr", 'False')
config.option.markexpr = f"always_run or ({markexpr})"
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.