【问题标题】:Is there a way to tell pytest which tests to run based on a marker attribute value?有没有办法告诉 pytest 根据标记属性值运行哪些测试?
【发布时间】:2020-04-07 04:37:30
【问题描述】:

我有一个使用标记的版本分隔的测试:

例子:

@pytest.mark.version("1.0")
def test_does_something():
     assert 1

@pytest.mark.version("1.0.1")
def test_does_another_thing():
     assert 0

@pytest.mark.version("1.1.1")
def test_does_nothing():
     assert 0

@pytest.mark.version("2.3.1")
def test_example():
     assert 1

这个想法是根据命令行传递的标记值执行测试,例如:

pytest my_file.py -m "version("1.1") and version("2.3.1")

【问题讨论】:

    标签: python pytest command-line-arguments


    【解决方案1】:

    我们可以有一个帖子收集过滤器,如下所述:
    https://docs.pytest.org/en/latest/writing_plugins.html

    此过滤器会删除未指定版本或不匹配的所有测试。

    def pytest_collection_modifyitems(session, config, items):
        markerExpr = config.option.markexpr
        if not markerExpr:
            return
        tokens = markerExpr.split("version=")
        if len(tokens) == 0:
            return
        version = tokens[1]
        selected = []
        deselected = []
        for item in items:
            versionMarker = item.get_closest_marker('version')
            print(versionMarker)
            if not versionMarker:
                deselected.append(item)
                continue
            found = False
            if len(versionMarker.args) == 1:
                if versionMarker.args[0] == version:
                    found = True
                    selected.append(item)
            if not found:
                deselected.append(item)
        config.option.markexpr = "version"
        config.hook.pytest_deselected(items=deselected)
        items[:] = selected
    

    这个怎么用?

    pytest -v -m "version=1.1.1" 
    

    t.py

    import pytest
    
    
    @pytest.mark.version("1.0")
    def test_does_something():
         assert 1
    
    @pytest.mark.version("1.0.1")
    def test_does_another_thing():
         assert 0
    
    @pytest.mark.version("1.1.1")
    def test_does_nothing():
         assert 0
    
    @pytest.mark.version("2.3.1")
    def test_example():
         assert 1
    

    【讨论】:

      【解决方案2】:

      按照文档中给出的example,您可以使用 conftest.py 文件以正确配置标记:

      # content of conftest.py
      
      import pytest
      
      def pytest_addoption(parser):
          parser.addoption(
              "-V",
              action="store",
              metavar="VERSION",
              help="only run tests matching the version VERSION.",
          )
      
      def pytest_configure(config):
          # register an additional marker
          config.addinivalue_line(
              "markers", "version(x): mark test to run only on x version"
          )
      
      def pytest_runtest_setup(item):
          versions = [mark.args[0] for mark in item.iter_markers(name="version")]
          print('versions: %s' % versions)
          print('item: %s' % item)
          if versions:
              if item.config.getoption("-V") not in versions:
                  pytest.skip("test requires version in {!r}".format(versions))
      

      使用以下命令运行它(例如,仅 1.0.1 版):

      pytest -V 1.0.1
      

      它将打印,除其他外:

      ...
      collected 4 items                                                                                                                                                                                             
      test_mark.py sFss
      ...
      1 failed, 3 skipped in 0.09s
      

      【讨论】:

      • 是的,我一直在使用这种方法,但我不想跳过测试,只是不要收集测试
      猜你喜欢
      • 2016-07-27
      • 1970-01-01
      • 2017-01-19
      • 2017-09-13
      • 2011-10-23
      • 1970-01-01
      • 2017-03-01
      • 2018-06-01
      • 1970-01-01
      相关资源
      最近更新 更多