在测试运行开始时动态选择 pytest 测试

Tum*_*tsu 3 python unit-testing pytest

我正在使用 pytest 为我的 Python 应用程序编写单元测试。我编写单元测试的大部分经验来自 Javacript 框架,例如 Jasmine,您可以在其中使用单词“fit”单独标记要在下一轮测试中运行的测试,或者使用单词“xit”标记要排除的测试。在开发过程中,当我只想运行非常特定的测试子集以减少运行时间和结果输出混乱时,“fit”非常好。Xit 已经使用 mark.skip 装饰器实现,但我想要合适。

我如何配置 pytest 来执行如下操作:

  • 收集所有测试
  • 检查是否有任何带有装饰器 @pytest.mark.only 装饰器标记的测试。如果找到任何测试,则仅运行这些测试,否则运行所有测试

我知道我可以选择使用带有 -m 标志的命令行运行的测试,但我想动态检测可运行测试的子集,以便在开发过程中我不必使用一个命令使用两个不同的命令运行测试有 -m 标志,其他没有该标志。

我想 conftest.py 可能是添加此逻辑的地方,但我找不到有关其配置的太多信息。

Li *_*eng 6

Pytest 插件pytest_collection_modifyitems似乎就是你所需要的。(将以下代码放入您的中conftest.py

def pytest_collection_modifyitems(session, config, items):
    """ called after collection has been performed, may filter or re-order
    the items in-place."""

    found_only_marker = False
    for item in items.copy():
        if item.get_marker('only'):
            if not found_only_marker:
                items.clear()
                found_only_marker = True
            items.append(item)
Run Code Online (Sandbox Code Playgroud)

列表items是收集的测试。

注意: list.copy仅适用于python3,如果您使用python2,请参考:如何克隆或复制列表?

这个想法很简单:

收集所有测试(项目)后,只需检查任何测试中是否存在标记“only”。如果是,则清除列表items并仅添加标记为 的测试only,如果不是,则保持项目不变。