繁体   English   中英

如何在 py.test 运行中多次重复每个测试?

[英]How can I repeat each test multiple times in a py.test run?

我想按顺序运行每个选定的 py.test 项目任意次数。
我没有看到执行此操作的任何标准 py.test 机制。

我试图在pytest_collection_modifyitems()挂钩中执行此操作。 我修改了传入的项目列表,以多次指定每个项目。 测试项的第一次执行按预期工作,但这似乎给我的代码带来了一些问题。

此外,我希望每次运行都有一个唯一的测试项目 object,因为我在各种报告代码中使用 id(项目)作为键。 不幸的是,我找不到任何 py.test 代码来复制测试项目, copy.copy()不起作用, copy.deepcopy()出现异常。

有人可以建议多次执行测试的策略吗?

一种可能的策略是参数化有问题的测试,但不明确使用参数。

例如:

@pytest.mark.parametrize('execution_number', range(5))
def run_multiple_times(execution_number):
    assert True

上面的测试应该运行五次。

查看参数化文档: https : //pytest.org/latest/parametrize.html

pytest 模块pytest-repeat为此目的而存在,我建议尽可能使用模块,而不是自己重新实现它们的功能。

要使用它,只需将pytest-repeat添加到您的requirements.txtpip install pytest-repeat ,然后使用--count n执行您的测试。

为了多次运行每个测试,我们将在生成测试时以编程方式参数化每个测试。

首先,让我们添加解析器选项(在其中一个 conftest.py 中包含以下内容):

def pytest_addoption(parser):
    parser.addoption('--repeat', action='store',
        help='Number of times to repeat each test')

现在我们添加一个“pytest_generate_tests”钩子。 这就是魔法发生的地方。

def pytest_generate_tests(metafunc):
    if metafunc.config.option.repeat is not None:
        count = int(metafunc.config.option.repeat)

        # We're going to duplicate these tests by parametrizing them,
        # which requires that each test has a fixture to accept the parameter.
        # We can add a new fixture like so:
        metafunc.fixturenames.append('tmp_ct')

        # Now we parametrize. This is what happens when we do e.g.,
        # @pytest.mark.parametrize('tmp_ct', range(count))
        # def test_foo(): pass
        metafunc.parametrize('tmp_ct', range(count))

在没有重复标志的情况下运行:

(env) $ py.test test.py -vv
============================= test session starts ==============================
platform darwin -- Python 2.7.5 -- py-1.4.20 -- pytest-2.5.2 -- env/bin/python
collected 2 items 

test.py:4: test_1 PASSED
test.py:8: test_2 PASSED

=========================== 2 passed in 0.01 seconds ===========================

使用重复标志运行:

(env) $ py.test test.py -vv --repeat 3
============================= test session starts ==============================
platform darwin -- Python 2.7.5 -- py-1.4.20 -- pytest-2.5.2 -- env/bin/python
collected 6 items 

test.py:4: test_1[0] PASSED
test.py:4: test_1[1] PASSED
test.py:4: test_1[2] PASSED
test.py:8: test_2[0] PASSED
test.py:8: test_2[1] PASSED
test.py:8: test_2[2] PASSED

=========================== 6 passed in 0.01 seconds ===========================

进一步阅读:

根据 Frank T 的建议,我在pytest_generate_tests()标注中找到了一个非常简单的解决方案:

parser.addoption ('--count', default=1, type='int', metavar='count', help='Run each test the specified number of times')

def pytest_generate_tests (metafunc):
    for i in range (metafunc.config.option.count):
        metafunc.addcall()

现在执行py.test --count 5会导致每个测试在测试会话中执行五次。

它不需要对我们现有的任何测试进行更改。

根据我在这里看到的内容,并且鉴于我已经在pytest_collection_modifyitems进行了一些测试过滤,我选择的方法如下。 conftest.py

def pytest_addoption(parser):
    parser.addoption ('--count', default=1, type='int', metavar='count', help='Run each test the specified number of times')


def pytest_collection_modifyitems(session, config, items):
    count = config.option.count
    items[:] = items * count  # add each test multiple times

虽然pytest-repeat (最普遍的回答)不工作unittest类测试, pytest-flakefinder的作用:

pip install pytest-flakefinder
pytest --flake-finder --flake-runs=5 tests...

在找到test-flakefinder之前,我写了一个执行类似操作的脚本的小技巧。 你可以在这里找到它。 脚本的顶部包括如何运行它的说明。

截至 2020 年 10 月 31 日,有更好的方法可以做到这一点。 https://pypi.org/project/pytest-repeat/


只需pip install pytest-repeat并使用--count 示例: pytest --count=10 test_file.py

很长一段时间以来,我一直在寻找一个简单的解决方案。 我只需要运行一个测试 n 次。 他不应该跌倒一次。 我尽可能简单和愚蠢地解决了这个问题,但它对我有用。

def run_multiple_times(number):
    i = 0
    while i < number:
        #test
        i += 1
run_multiple_times(5)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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