victory的博客

长安一片月,万户捣衣声

0%

pytest | fixtures执行顺序及清理顺序

pytest fixtures执行顺序和清理顺序

  1. fixtures执行顺序

pytest一个test请求多个fixture时,fixtures的执行顺序是什么?

以下面的demo为例,在这段代码中test_string_only请求了append_first,order,fisrt_entry三个fixtures,从代码中可以看出append_first fixture依赖于order和first_entry fixtures。

pytest会对多个fixtures进行依赖解析如果一个fixture依赖于其他fixture(s),那么被依赖的fixtures会先于依赖它们的fixture执行

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
# contents of test_append.py
import pytest


# Arrange
@pytest.fixture
def first_entry():
print("3 - first_entry fixture has been executed.")
return "a"


# Arrange
@pytest.fixture
def order():
print("2 - order fixture has been executed.")
return []


# Act
@pytest.fixture
def append_first(order, first_entry):
print("1 - append_first fixture has been executed.")
return order.append(first_entry)


def test_string_only(append_first, order, first_entry):
# Assert
assert order == [first_entry]

运行以上代码的结果如下:

1
2
3
4
5
6
7
8
9
10
============================= test session starts =============================
collecting ... collected 1 item

test_append.py::test_string_only
2 - order fixture has been executed.
3 - first_entry fixture has been executed.
1 - append_first fixture has been executed.
PASSED [100%]

============================== 1 passed in 0.04s ==============================

从运行结果可以看出,order fixture和first_entry fixture先于append_firt fixture执行。

fixtures之间不存在依赖关系的,按照它们被声明的顺序执行,以下面的demo为例,假设有两个 fixtures,fixture A 和 fixture B,其中 fixture A 依赖于 fixture B。下面是一个示例来说明它们按照声明顺序执行的情况:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
import pytest

@pytest.fixture
def fixture_b():
print("Executing fixture B")
yield
print("Cleaning up fixture B")

@pytest.fixture
def fixture_a(fixture_b):
print("Executing fixture A")
yield
print("Cleaning up fixture A")

def test_example(fixture_a, fixture_b):
print("Executing test example")
assert True

在这个例子中,fixture_bfixture_a 都使用了 @pytest.fixture 装饰器进行声明。在测试函数 test_example 的参数列表中,fixture_bfixture_a 之前声明。

当运行这个测试时,pytest 会首先执行 fixture_b,然后执行 fixture_a。这是因为 fixture_a 依赖于 fixture_b,所以需要先执行它。最后,测试函数 test_example 会被执行。

输出结果如下:

1
2
3
4
5
Executing fixture B
Executing fixture A
Executing test example
Cleaning up fixture A
Cleaning up fixture B

可以看到,fixtures 是按照它们被声明的顺序执行的,首先是 fixture_b,然后是 fixture_a

  1. fixtures清理顺序

每个fixture在它自己的代码块执行完毕后立即进行清理。有依赖关系的fixtures的清理工作先从清理被依赖fixture开始,例如fixture A依赖于fixture B,那么执行顺序将会是:首先执行fixture B,然后执行fixture A,最后清理工作会先从fixture A开始,然后是fixture B。这种设计确保了每个fixture能及时清理自己使用的资源,避免了潜在的资源冲突或泄露问题。