pytest固定程序是以什么顺序执行的?

51 人关注

对于我正在测试的一个应用程序,我想创建一个 autouse=True 的固定程序,如果测试者试图意外地发送电子邮件,则 monkeypatches smtplib.SMTP.connect 将失败。

然而,在我确实期望测试发送电子邮件的情况下。我想用一个不同的夹具来记录这些邮件(很可能是通过使用 smtpserver 的夹具,从 pytest-localserver connect 方法的猴子补丁来使用该夹具返回的主机/端口)。

当然,这只有在自动执行的夹具在另一个夹具(作为funcarg加载)之前被执行时才能工作。是否有任何特定的灯具执行顺序和/或有办法保证执行顺序?

3 个评论
一个非常有道理的问题,我见过许多灯具被滥用的情况,最麻烦的事情之一是哪个灯具在哪个之前运行。
另一个有用的技巧是,固定程序可以检查测试函数的pytest标记。这意味着你可以 @mark 需要做一些特殊的测试,然后,使用请求对象,检查测试函数是否有标记。如果有,就在你的夹具中执行一个不同的动作。
4xy
如果能知道拆解的顺序也很好
python
fixtures
pytest
ThiefMaster
ThiefMaster
发布于 2014-09-04
5 个回答
Chronial
Chronial
发布于 2019-02-20
已采纳
0 人赞同

控制固定程序执行顺序的最简单方法是在后面的固定程序中请求前一个固定程序。所以要确保 b a 之前运行。

@pytest.fixture(autouse=True, scope="function")
def b():
@pytest.fixture(scope="function")
def a(b):

关于一般固定装置的解决顺序的细节,见马克西姆的精彩回答如下或者看一下文件.

在pytest 3.0.2上似乎不起作用(没有自动鼠标)。试图将capfd与另一个创建sys.stdout的类的夹具一起使用,该类将sys.stdout保存到一个变量中:避免夹具捕获输出,试图像这样强制capfd先设置,却没有。
关于pytest 3.0.2和 "没有自动鼠标 "是什么意思?这段代码在pytest 3.0.2和3.0.3(最新)中运行良好。
我看到这个订单失败的大部分时间是由于我的一个固定装置由于错误而没有完成,仔细看看设置错误
Maxim
Maxim
发布于 2019-02-20
0 人赞同

TL;DR

在建立夹具评估顺序时,有3个方面被一起考虑,方面本身是按优先顺序排列的。

  • Fixture dependencies - fixtures are evaluated from rootest required back to one required in test function .
  • Fixture scope - fixtures are evaluated from session through module to function scoped. On the same scope autouse fixtures are evaluated before non-autouse ones.
  • Fixture position in test function arguments - fixtures are evaluated in order of presence in test function arguments, from leftest to rightest .
  • 下面是官方的解释和代码示例的链接

    https://docs.pytest.org/en/stable/fixture.html#fixture-instantiation-order

    UPDATE

    目前的文档提到了3个因素,作为唯一的考虑因素,同时不鼓励依赖其他因素(如测试函数参数的顺序)。

  • scope
  • dependencies
  • autouse
  • 上面的链接是 过时的 . See 更新链接

    第三点 "存在的顺序......从最左到最右 "并没有得到pytest文档的证实。从 docs.pytest.org/en/stable/fixture.html#fixture-order :"......所要求的固定装置的顺序对执行顺序没有影响,超越了巧合"
    jfs
    该链接只提到了3个案例 : 1- 范围 2- 依赖性 3- 自主性 注意:列表中没有 "测试函数参数中的夹具位置"。请不要依赖它。
    谢谢你们的指出,我已经更新了答案。
    ebeezer
    ebeezer
    发布于 2019-02-20
    0 人赞同

    我在使用两个 function 范围的autouse灯具时遇到了这个问题。我想让灯具 b 在灯具 a 之前运行,但每次都是 a 先运行。我想也许是字母顺序的问题,所以我把 a 改名为 c ,现在 b 先运行。Pytest似乎没有这方面的记录。这只是一个幸运的猜测。:-)

    这是针对自动执行的固定程序。考虑到更广泛的范围(例如: module session ),当pytest遇到一个需要它的测试时,就会执行一个夹具。因此,如果有两个测试,而第一个测试使用了一个名为 session 范围的夹具 sb ,而不是名为 sa 的夹具,那么 sb 将首先被执行。当下一个测试运行时,它将启动 sa ,假设它需要 sa

    可以确认为py.test 2.6.4版本。
    我也在使用2.6.4。
    这个答案最好删除,因为它让人们通过使用按字母顺序排列的 "功能 "来 "节省时间"。这真是太糟糕了
    这个回答让我明白,我不能正确地执行灯具的某些特定顺序。而且我不想使用字母顺序,所以我只是试图以一种不依赖顺序的方式重写我的灯具。TL;DR仍然认为这很有帮助:)
    Pytest文档说,这种行为 "除了巧合之外,对执行顺序没有影响。虽然pytest会努力确保像这样的巧合在不同的运行中保持一致,但这并不是应该依赖的东西。"
    flub
    flub
    发布于 2019-02-20
    0 人赞同

    我记得你可以依靠较高范围的固定程序先被执行。 因此,如果你创建了一个会话范围的autouse夹具来对 smtplib.SMTP.connect 进行monkeypatch,那么你可以创建一个函数范围的夹具,为一个测试撤销这个monkeypatch,之后再恢复它。 我认为最简单的方法是创建你自己的 smtpserver 夹具,该夹具依赖于 disallow_smtp 夹具以及以及 pytest-localserver 中的 smtpserver 夹具,然后处理所有的设置和拆分,使这两者一起工作。

    这就是 pytest-django 处理数据库访问的模糊方式,你可以试着看一下那里的代码,但它远不是一个简单的例子,而且有许多它自己的奇怪之处。

    sandeep shewale
    sandeep shewale
    发布于 2019-02-20
    0 人赞同

    在以下代码的帮助下,我们可以轻松地设置固定装置/函数的执行顺序

    e.g:-

    execution order first

    @pytest.mark.order(1)