简体   繁体   English

pytest是否支持“默认”标记?

[英]Does pytest support “default” markers?

I am using pytest to test python models for embedded systems. 我正在使用pytest来测试嵌入式系统的python模型。 Features to be tested vary by platform. 要测试的功能因平台而异。 ( I'm using 'platform' in this context to mean an embedded system type, not an OS type). (我在这个上下文中使用'platform'来表示嵌入式系统类型,而不是OS类型)。

The most straightforward way to organize my tests would be to allocate them to directories based on platform type. 组织我的测试最直接的方法是根据平台类型将它们分配给目录。

/platform1
/platform2
/etc.

pytest /platform1 pytest / platform1

This quickly became hard to support as many features overlap across platforms. 由于许多功能在不同平台上重叠,因此很快就难以支持。 I've since moved my tests into a single directory, with tests for each functional area assigned to a single filename (test_functionalityA.py, for example). 我已经将我的测试移动到一个目录中,每个功能区域的测试分配给一个文件名(例如test_functionalityA.py)。 I then use pytest markers to indicate which tests within a file apply to a given platform. 然后我使用pytest标记来指示文件中的哪些测试适用于给定平台。

@pytest.mark.all_platforms
def test_some_functionalityA1():
    ...

@pytest.mark.platform1
@pytest.mark.platform2
def test_some_functionlityA2():
    ...

While I would love to get 'conftest' to automatically detect the platform type and only run the appropriate tests, I've resigned myself to specifying which tests to run on the command line. 虽然我很乐意让'conftest'自动检测平台类型并且只运行相应的测试,但我已经决定在命令行上指定要运行的测试。

pytest -m "(platform1 or all_platforms)" pytest -m“(platform1或all_platforms)”

The Question: (finally!) 问题:(终于!)

Is there a way to simplify things and have pytest run all unmarked tests by default and additionally all tests passed via '-m' on the command-line? 有没有办法简化事情并让pytest默认运行所有未标记的测试,另外所有测试都通过命令行上的'-m'传递?

For example: pytest -m "platform1" 例如:pytest -m“platform1”

would run tests marked @pytest.mark.platform1 as well as all tests marked @pytest.mark.all_platforms or even all tests with no @pytest.mark at all? 会运行标记@ pytest.mark.platform1的测试以及所有标记为@ pytest.mark.all_platforms的测试,甚至所有测试都没有@ pytest.mark吗?

Given the large amount of shared functionality, being able to drop the @pytest.mark.all_platforms line would be a big help. 鉴于大量共享功能,能够删除@ pytest.mark.all_platforms行将是一个很大的帮助。

Let's tackle the full problem. 让我们解决完整的问题。 I think you can put a conftest.py file along with your tests and it will take care to skip all non-matching tests (non-marked tests will always match and thus never get skipped). 我认为你可以把一个conftest.py文件和你的测试放在一起,它会注意跳过所有不匹配的测试(非标记的测试总是匹配,因此永远不会被跳过)。 Here i am using sys.platform but i am sure you have a different way to compute your platform value. 这里我使用的是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))

With this you can mark your tests like this:: 有了它,你可以像这样标记你的测试::

# 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

and if you run with:: 如果你运行::

$ py.test -rs

then you can run it and will see at least two test skipped and always at least one test executed:: 然后你可以运行它,并会看到至少两个测试被跳过,并且总是至少执行一次测试::

then you will see two test skipped and two executed tests as expected:: 然后你会看到两个测试跳过和两个执行测试按预期::

$ 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 ====================

Note that if you specify a platform via the marker-command line option like this:: 请注意,如果您通过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 ==================

then the unmarked-tests will not be run. 那么未标记的测试将不会运行。 It is thus a way to restrict the run to the specific tests. 因此,这是一种将运行限制为特定测试的方法。

Late to the party, but I just solved a similar problem by adding a default marker to all unmarked tests. 晚了,但我刚刚通过为所有未标记的测试添加默认标记解决了类似的问题。

As a direct answer to the Question: you can have unmarked tests always run, and include marked test only as specified via the -m option, by adding the following to the conftest.py 作为问题的直接答案:您可以始终运行未标记的测试,并且仅通过-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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM