我正在使用pytest来测试嵌入式系统的python模型.要测试的功能因平台而异.(我在这个上下文中使用'platform'来表示嵌入式系统类型,而不是OS类型).
组织我的测试最直接的方法是根据平台类型将它们分配给目录.
/platform1
/platform2
/etc.
Run Code Online (Sandbox Code Playgroud)
pytest/platform1
由于许多功能在不同平台上重叠,因此很快就难以支持.我已经将我的测试移动到一个目录中,每个功能区域的测试分配给一个文件名(例如test_functionalityA.py).然后我使用pytest标记来指示文件中的哪些测试适用于给定平台.
@pytest.mark.all_platforms
def test_some_functionalityA1():
...
@pytest.mark.platform1
@pytest.mark.platform2
def test_some_functionlityA2():
...
Run Code Online (Sandbox Code Playgroud)
虽然我喜欢得到"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))
Run Code Online (Sandbox Code Playgroud)
有了它,你可以像这样标记你的测试::
# 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
Run Code Online (Sandbox Code Playgroud)
如果你运行::
$ py.test -rs
Run Code Online (Sandbox Code Playgroud)
然后你可以运行它,并会看到至少两个测试被跳过,并且总是至少执行一次测试::
然后你会看到两个测试跳过和两个执行测试按预期::
$ 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 ====================
Run Code Online (Sandbox Code Playgroud)
请注意,如果您通过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 ==================
Run Code Online (Sandbox Code Playgroud)
那么未标记的测试将不会运行.因此,这是一种将运行限制为特定测试的方法.
迟到了,但我刚刚通过向所有未标记的测试添加默认标记解决了类似的问题。
作为问题的直接答案:您可以始终运行未标记的测试,并仅包含通过-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})"
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1306 次 |
| 最近记录: |