Python pytest中的测试用例执行顺序

Python pytest中的测试用例执行顺序,python,pytest,Python,Pytest,我正在使用pytest。我在一个目录中有两个文件。在其中一个文件中,有一个长时间运行的测试用例生成一些输出。在另一个文件中,有一个读取该输出的测试用例。如何确保这两个测试用例的正确执行顺序?除了按正确的顺序将测试用例放在同一个文件中之外,还有其他选择吗?通常,您可以使用其配置pytest的任何部分的行为 在您的例子中,您需要“pytest\u collection\u modifyitems”钩子,它允许您对收集的测试进行重新排序 这就是说,排序测试似乎应该更容易——毕竟这是Python!因此,

我正在使用pytest。我在一个目录中有两个文件。在其中一个文件中,有一个长时间运行的测试用例生成一些输出。在另一个文件中,有一个读取该输出的测试用例。如何确保这两个测试用例的正确执行顺序?除了按正确的顺序将测试用例放在同一个文件中之外,还有其他选择吗?

通常,您可以使用其配置pytest的任何部分的行为

在您的例子中,您需要“pytest\u collection\u modifyitems”钩子,它允许您对收集的测试进行重新排序

这就是说,排序测试似乎应该更容易——毕竟这是Python!因此,我编写了一个用于排序测试的插件:。请检查或从中安装。现在我建议使用@pytest.mark.first和@pytest.mark.second,或@pytest.mark.order#标记之一,但我对更有用的API有一些想法。建议(欢迎:)


编辑:PyTestRead现在似乎被放弃了,你也可以签出(作者原创项目的一个分支)。

也许你可以考虑使用PyTestPuxin,在那里你可以轻松地设置测试依赖关系。 小心——评论表明这并不适用于所有人

@pytest.mark.dependency()
def test_long():
    pass

@pytest.mark.dependency(depends=['test_long'])
def test_short():
    pass
这样,只有当
test\u long
成功时,才会执行
test\u short
,并强制执行序列。

还有一个插件似乎符合您的要求。

尝试以下方法:

@pytest.fixture(xxx)
def test_A():
    pass
    yield
    pass

@pytest.mark.usefixtures('test_A')
def test_B():
    pass
main.py:

import functools
import pytest
from demo import test_foo,test_hi

def check_depends(depends):
    try:
        for dep in depends:
            dep()
    except Exception as e:
        return dep
    else:
        return True

def pytest_depend(depends):
    def pytest_depend_decorator(func):
        stat = check_depends(depends)
        if stat is True:
            return func
        else:
            return pytest.mark.skip(True, reason="%s[skip] --> %s[Failed]" % (func.__name__, stat.__name__))(func)
    return pytest_depend_decorator


@pytest_depend([test_foo,test_hi])
def test_bar():
    pass

@pytest_depend([test_foo,test_hi])
def test_bar2():
    pass
demo.py:

def test_hi():
    pass
def test_foo():
    assert False

平台linux——Python 3.5.2、pytest-3.8.2、py-1.6.0、pluggy-0.7.1--/usr/bin/python3

pytest-vrsx./plugin.py


确保您已安装pytest订购包。 要确认,请转到Pycharm设置>>项目解释器>>并查找pytest顺序: 如果不可用,请安装它。 Pycharm设置>>项目解释器>>单击+按钮并搜索Pycharm,然后安装它。 瞧!!它肯定会起作用。

使用--random not recombination'选项或'-p no:random'可在pytest random插件中找到,这将按照模块中提到的顺序运行测试

模块:

import pytest

def test_three():
    assert True

def test_four():
    assert True

def test_two():
    assert True

def test_one():
    assert True
(tmp.w95BqE188N) rkalaiselvan@dev-rkalaiselvan:~/$ py.test --randomly-dont-reorganize test_dumm.py
======================================================================== test session starts ========================================================================
platform linux2 -- Python 2.7.12, pytest-3.10.1, py-1.5.4, pluggy-0.7.1 -- /tmp/tmp.w95BqE188N/bin/python2
cachedir: .pytest_cache
Using --randomly-seed=1566829391
rootdir: /home/rkalaiselvan, inifile: pytest.ini
plugins: randomly-1.2.3, timeout-1.3.1, cov-2.6.0, mock-1.10.0, ordering-0.6
collected 4 items

test_dumm.py::test_three PASSED
test_dumm.py::test_four PASSED
test_dumm.py::test_two PASSED
test_dumm.py::test_one PASSED

(tmp.w95BqE188N) rkalaiselvan@dev-rkalaiselvan:~/$ py.test -p no:randomly test_dumm.py
======================================================================== test session starts ========================================================================
platform linux2 -- Python 2.7.12, pytest-3.10.1, py-1.5.4, pluggy-0.7.1 -- /tmp/tmp.w95BqE188N/bin/python2
cachedir: .pytest_cache
Using --randomly-seed=1566829391
rootdir: /home/rkalaiselvan, inifile: pytest.ini
plugins: randomly-1.2.3, timeout-1.3.1, cov-2.6.0, mock-1.10.0, ordering-0.6
collected 4 items

test_dumm.py::test_three PASSED
test_dumm.py::test_four PASSED
test_dumm.py::test_two PASSED
test_dumm.py::test_one PASSED
pip install pytest-order
import pytest

@pytest.mark.order(1)
def test_foo():
    assert True

@pytest.mark.order(2)
def test_bar():
    assert True
执行:

import pytest

def test_three():
    assert True

def test_four():
    assert True

def test_two():
    assert True

def test_one():
    assert True
(tmp.w95BqE188N) rkalaiselvan@dev-rkalaiselvan:~/$ py.test --randomly-dont-reorganize test_dumm.py
======================================================================== test session starts ========================================================================
platform linux2 -- Python 2.7.12, pytest-3.10.1, py-1.5.4, pluggy-0.7.1 -- /tmp/tmp.w95BqE188N/bin/python2
cachedir: .pytest_cache
Using --randomly-seed=1566829391
rootdir: /home/rkalaiselvan, inifile: pytest.ini
plugins: randomly-1.2.3, timeout-1.3.1, cov-2.6.0, mock-1.10.0, ordering-0.6
collected 4 items

test_dumm.py::test_three PASSED
test_dumm.py::test_four PASSED
test_dumm.py::test_two PASSED
test_dumm.py::test_one PASSED

(tmp.w95BqE188N) rkalaiselvan@dev-rkalaiselvan:~/$ py.test -p no:randomly test_dumm.py
======================================================================== test session starts ========================================================================
platform linux2 -- Python 2.7.12, pytest-3.10.1, py-1.5.4, pluggy-0.7.1 -- /tmp/tmp.w95BqE188N/bin/python2
cachedir: .pytest_cache
Using --randomly-seed=1566829391
rootdir: /home/rkalaiselvan, inifile: pytest.ini
plugins: randomly-1.2.3, timeout-1.3.1, cov-2.6.0, mock-1.10.0, ordering-0.6
collected 4 items

test_dumm.py::test_three PASSED
test_dumm.py::test_four PASSED
test_dumm.py::test_two PASSED
test_dumm.py::test_one PASSED
pip install pytest-order
import pytest

@pytest.mark.order(1)
def test_foo():
    assert True

@pytest.mark.order(2)
def test_bar():
    assert True

在试图修复pytest顺序“问题”时,务必记住,按照指定的顺序运行测试似乎是pytest的默认设置


事实证明,我的测试顺序不正确是因为其中一个包-
pytest依赖项
pytest依赖项
pytest顺序
。一旦我用
pip uninstall package\u name
卸载了它们,问题就消失了。看起来它们有副作用。默认情况下,它会随机执行这些步骤。因此,使用此选项按顺序执行

安装时使用:

import pytest

def test_three():
    assert True

def test_four():
    assert True

def test_two():
    assert True

def test_one():
    assert True
(tmp.w95BqE188N) rkalaiselvan@dev-rkalaiselvan:~/$ py.test --randomly-dont-reorganize test_dumm.py
======================================================================== test session starts ========================================================================
platform linux2 -- Python 2.7.12, pytest-3.10.1, py-1.5.4, pluggy-0.7.1 -- /tmp/tmp.w95BqE188N/bin/python2
cachedir: .pytest_cache
Using --randomly-seed=1566829391
rootdir: /home/rkalaiselvan, inifile: pytest.ini
plugins: randomly-1.2.3, timeout-1.3.1, cov-2.6.0, mock-1.10.0, ordering-0.6
collected 4 items

test_dumm.py::test_three PASSED
test_dumm.py::test_four PASSED
test_dumm.py::test_two PASSED
test_dumm.py::test_one PASSED

(tmp.w95BqE188N) rkalaiselvan@dev-rkalaiselvan:~/$ py.test -p no:randomly test_dumm.py
======================================================================== test session starts ========================================================================
platform linux2 -- Python 2.7.12, pytest-3.10.1, py-1.5.4, pluggy-0.7.1 -- /tmp/tmp.w95BqE188N/bin/python2
cachedir: .pytest_cache
Using --randomly-seed=1566829391
rootdir: /home/rkalaiselvan, inifile: pytest.ini
plugins: randomly-1.2.3, timeout-1.3.1, cov-2.6.0, mock-1.10.0, ordering-0.6
collected 4 items

test_dumm.py::test_three PASSED
test_dumm.py::test_four PASSED
test_dumm.py::test_two PASSED
test_dumm.py::test_one PASSED
pip install pytest-order
import pytest

@pytest.mark.order(1)
def test_foo():
    assert True

@pytest.mark.order(2)
def test_bar():
    assert True
编写测试方法,如下所示:

import pytest

def test_three():
    assert True

def test_four():
    assert True

def test_two():
    assert True

def test_one():
    assert True
(tmp.w95BqE188N) rkalaiselvan@dev-rkalaiselvan:~/$ py.test --randomly-dont-reorganize test_dumm.py
======================================================================== test session starts ========================================================================
platform linux2 -- Python 2.7.12, pytest-3.10.1, py-1.5.4, pluggy-0.7.1 -- /tmp/tmp.w95BqE188N/bin/python2
cachedir: .pytest_cache
Using --randomly-seed=1566829391
rootdir: /home/rkalaiselvan, inifile: pytest.ini
plugins: randomly-1.2.3, timeout-1.3.1, cov-2.6.0, mock-1.10.0, ordering-0.6
collected 4 items

test_dumm.py::test_three PASSED
test_dumm.py::test_four PASSED
test_dumm.py::test_two PASSED
test_dumm.py::test_one PASSED

(tmp.w95BqE188N) rkalaiselvan@dev-rkalaiselvan:~/$ py.test -p no:randomly test_dumm.py
======================================================================== test session starts ========================================================================
platform linux2 -- Python 2.7.12, pytest-3.10.1, py-1.5.4, pluggy-0.7.1 -- /tmp/tmp.w95BqE188N/bin/python2
cachedir: .pytest_cache
Using --randomly-seed=1566829391
rootdir: /home/rkalaiselvan, inifile: pytest.ini
plugins: randomly-1.2.3, timeout-1.3.1, cov-2.6.0, mock-1.10.0, ordering-0.6
collected 4 items

test_dumm.py::test_three PASSED
test_dumm.py::test_four PASSED
test_dumm.py::test_two PASSED
test_dumm.py::test_one PASSED
pip install pytest-order
import pytest

@pytest.mark.order(1)
def test_foo():
    assert True

@pytest.mark.order(2)
def test_bar():
    assert True


一般来说,让测试用例相互依赖不是一个好主意。如果您需要在两个测试用例中使用相同的数据,为什么不将其添加到
设置
部分?我知道。我也不喜欢它,但现在我需要它。我不想把它添加到设置部分,因为它需要15-20分钟。嗯,有没有办法模拟一下?如果没有,那么您可能需要明确地链接两个测试(或使它们成为一个大型测试),或者环境设置代码进入setUpClass方法,它将运行一次,并且在任何测试运行之前运行。或者,您可以将惰性初始化模式代码写入setup方法。或者甚至写入-
initialized=False def test\u mytest1:if initialized:somelongfunction()initialized=True
而使用框架。考虑一下这种可能性,如果你需要订购测试,它们不再是单元测试,你需要考虑一个新的脚手架工作来简化它。感谢您创建这个插件。您可以修改它,使其只提取尾随数字作为顺序吗。例如,如果我说@pytest.mark.custom1,那么订单应该是1。这将大有帮助!我可以试试。我认为v0.2有一个“顺序”标记,而不是任意的标记。你能在pytest ordering的github页面上写下这个特性请求吗?hooks链接应该指向:我在pytest v3.0.3中注意到,
pytest\u collection\u modifyitems()
中的
items
列表中的测试顺序与实际执行测试的顺序不匹配,我也不确定原因。@meowsqueak您是否已推断出顺序更改的原因?以上内容对我来说不适用于顺序排序。例如:如果你改变顺序。长期以来,我一直依赖短期贷款。在这种情况下,long被跳过。这个答案使用pytest插件。测试位于两个不同的模块中,正如在中指出的,仍然不可能让一个测试依赖于另一个模块中的另一个测试。这不适用于pytest依赖项0.5.1(我刚刚尝试过)。pytest dependency只会跳过一个测试,如果它还没有达到,它不会排序测试。我将投票否决这个答案,因为这可能是dependency-0.5.1中的一个错误,或者排序功能不再在pytest dependency的范围内。另请参见Frank T.的回答中已经提到了这个插件,并且在这个回答的三年前就发布了。呃,但是他没有提到这个名字。这就是为什么我可能完全忽略了这一点。现在也提到了名称:-)虽然这段代码可以回答这个问题,但最好解释如何解决问题,并提供代码作为示例或参考。仅代码的答案可能会令人困惑,并且缺少上下文。OP没有提到PyCharm按照指定的顺序运行测试似乎是默认的pytest@Hemil,您能通过文档链接验证这一点吗?我不确定是否建议使用此选项。它将为每个测试条运行test_foo和test_hi,而不是只运行一次。此外,如果test_foo或test_hi被称为duri