pytest 装置按什么顺序执行?

问题描述 投票:0回答:5

对于我正在测试的应用程序,我想创建一个

autouse=True
固定装置,如果他们尝试意外发送电子邮件,它会对
smtplib.SMTP.connect
进行猴子修补,以使测试失败。

但是,在我确实希望测试发送电子邮件的情况下,我想使用不同的装置来记录这些电子邮件(最有可能通过使用

smtpserver
中的
pytest-localserver
装置并猴子修补
connect
方法来使用主机) /该设备返回的端口)

当然,只有当自动使用固定装置在其他固定装置(作为 funcarg 加载)之前执行时,这才有效。是否有特定的夹具执行顺序和/或有办法保证执行顺序?

python fixtures pytest
5个回答
58
投票

控制夹具执行顺序的最简单方法是仅在后一个夹具中请求前一个夹具。因此,为了确保

b
a
之前运行:

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

@pytest.fixture(scope="function")
def a(b):
    pass

有关一般夹具分辨率顺序的详细信息,请参阅下面Maxim 的出色回答 或查看文档


31
投票

建筑装置评估顺序时会同时考虑 3 个方面,各个方面本身按优先顺序排列:

  • 夹具依赖性 - 夹具从所需的根评估回到测试功能中所需的
  • 灯具范围 - 灯具从
    session
    module
    function
    范围进行评估。在相同范围内,
    autouse
    灯具先于非自动使用灯具进行评估。
  • 测试函数参数中的夹具位置 - 夹具按照测试函数参数中存在的顺序进行评估,从leftestrightest

下面的链接带有代码示例的官方解释

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

更新:当前文档仅考虑了 3 个因素,同时不鼓励依赖其他因素(例如测试函数参数中的顺序):

  1. 范围
  2. 依赖关系
  3. 自动使用

12
投票

我只是遇到了两个

function
范围内的自动使用装置的问题。我希望夹具
b
在夹具
a
之前运行,但每次都是
a
先运行。我想可能是按字母顺序排列的,所以我将
a
重命名为
c
,现在
b
首先运行。 Pytest 似乎没有记录这一点。这只是一个幸运的猜测。 :-)

这是用于自动使用装置的。考虑到更广泛的范围(例如,

module
session
),当 pytest 遇到需要它的测试时,会执行固定装置。因此,如果有两个测试,并且第一个测试使用名为
session
sb
范围固定装置,而不是名为
sa
的固定装置,则
sb
将首先执行。当下一个测试运行时,它将开始
sa
,假设它需要
sa


2
投票

IIRC 您可以首先执行更高范围的装置。因此,如果您为monkeypatch创建了一个会话范围的自动使用固定装置

smtplib.SMTP.connect
,那么您可以创建一个函数范围的固定装置,该固定装置可以为一个测试撤消此monkeypatching,然后恢复它。我认为最简单的方法是创建您自己的
smtpserver
夹具,它依赖于
disallow_smtp
夹具以及来自
smtpserver
pytest-localserver
夹具,然后处理使这两个工作所需的所有设置和拆卸一起。

这大概是

pytest-django
处理数据库访问的方式,你可以尝试查看那里的代码,但它远不是一个简单的示例,并且有许多自己奇怪的事情。


-1
投票

借助以下代码,我们可以轻松设置装置/函数的执行顺序

例如:-

先执行顺序

@pytest.mark.order(1)

执行顺序第二

@pytest.mark.order(2)
© www.soinside.com 2019 - 2024. All rights reserved.