目录
- 4、Fixture的相互调用
- 5、Fixture复用
- 6、Fixture缓存返回结果
- 7、Fixture的后置处理
- (一)使用yield关键字实现后置
- (二)使用addfinalizer关键字实现后置
- (三)yield和addfinalizer的区别
4、Fixture的相互调用
示例:
import pytest
# 第一层fixture
@pytest.fixture()
def fixture_1():
data = \"fixture_1\"
print(\"这是第一层fixture\")
return data
# 第二层fixture
@pytest.fixture()
def fixture_2(fixture_1): # 在这里传递调用第一层fixture
print(\"这是第二层fixture\")
# 第三层fixture
@pytest.fixture()
@pytest.mark.usefixtures(\"fixture_1\") # 这种fixture相互调用方式不生效
def fixture_3():
print(\"这是第三层fixture\")
# 测试类
class TestClass:
def test_1(self, fixture_1):
print(\"调用第1层fixture,返回值为{}\".format(fixture_1))
def test_2(self, fixture_2):
print(\"调用第2层fixture,返回值为{}\".format(fixture_2))
def test_3(self, fixture_3):
print(\"调用第3层fixture\")
\"\"\"
执行结果
fixture/use_fixture_each_other.py::TestClass::test_1 这是第一层fixture
调用第1层fixture,返回值为fixture_1
PASSED
fixture/use_fixture_each_other.py::TestClass::test_2 这是第一层fixture
这是第二层fixture
调用第2层fixture,返回值为None
PASSED
fixture/use_fixture_each_other.py::TestClass::test_3 这是第三层fixture
调用第3层fixture
PASSED
\"\"\"
示例说明:
- 在调用存在相互调用的
fixture
时,执行顺序由顶层fixture
逐层向下执行(如示例test_2
优先执行fixture_1
再执行fixture_2
) - 当调用存在相互调用的
fixture
时,直接被调用的fixture
不会将自己接收到的返回值返回给调用方(如示例test_2
不会接收到由fixture_1
返回的值) - 相互调用
fixture
时不能使用pytest.mark.usefixture
装饰器(如示例fixture_3
)
5、Fixture复用
不同的测试函数可以请求相同的fixture
,每个测试函数都会获得该fixture的各自结果。不同的测试函数不互相影响,这样可以保证每个测试函数都能得到干净一致的数据。
示例
import pytest
@pytest.fixture()
def fixture_1():
return []
def test_1(fixture_1):
fixture_1.append(0)
print(f\"结果:{fixture_1}\")
def test_2(fixture_1):
fixture_1.append(9)
print(f\"结果:{fixture_1}\")
\"\"\"
执行结果
fixture/reuse_fixture.py::test_1 结果:[0]
PASSED
fixture/reuse_fixture.py::test_2 结果:[9]
PASSED
\"\"\"
示例说明
由上面例子可以看出,两个测试函数都调用了fixture_1
,但每次调用返回的结果是一样的,并不会因为test_1
中fixture_1
先添加了0而影响test_2
调用的fixture_1
返回的结果
6、Fixture缓存返回结果
在同一个测试函数多次调用同一个fixture
时,第一次执行该fixture
函数之后,会把返回结果缓存起来,不会再次执行它们
示例:
import pytest
@pytest.fixture()
def fixture_1():
print(\"执行fixture_1\")
return \"a\"
@pytest.fixture()
def fixture_2():
print(\"执行fixture_2\")
return []
@pytest.fixture()
def fixture_append(fixture_1, fixture_2):
print(\"执行fixture_append\")
fixture_2.append(fixture_1)
def test_fixture(fixture_append, fixture_2, fixture_1):
print(\"执行测试函数\")
print(fixture_2)
\"\"\"
执行结果
fixture/fixture_cache.py::test_fixture 执行fixture_1
执行fixture_2
执行fixture_append
执行测试函数
[\'a\']
PASSED
\"\"\"
示例说明:
由上面例子可以看出在fixture
函数fixture_append
中,fixture_1
第一次被请求返回字母a
,fixture_2
第一次被请求返回空列表,在测试函数test_fixture
中fixture_2
第二次被请求,但返回结果不是不是空列表,而是[\'a\']
。如果同一个fixture
在同一个测试函数中每次都去请求,那么必然返回的是空列表。
7、Fixture的后置处理
前面的案例都是加了前置处理,相当于setup()
,后置teardown()
在fixture
中是可以通过yield
关键字和addfinalizer
关键字来实现
(一)使用yield关键字实现后置
- 示例
import pytest
@pytest.fixture(autouse=True)
def fixture_3():
print(\"这是一个前置处理\")
yield
print(\"这是一个后置处理\")
def testcase_1(fixture_3):
print(\"这是测试用例1\")
def testcase_2(fixture_3):
print(\"这是测试用例2\")
\"\"\"
执行结果
fixture/use_fixture_3.py::testcase_1 这是一个前置处理
这是测试用例1
PASSED这是一个后置处理
fixture/use_fixture_3.py::testcase_2 这是一个前置处理
这是测试用例2
PASSED这是一个后置处理
\"\"\"
- 执行顺序
在前置处理中会根据fixture函数之间的线性关系顺序调用的,后置处理顺序会反过来
import pytest
@pytest.fixture()
def fixture_1():
print(\"这是fixture_1\")
return 1
@pytest.fixture()
def fixture_2(fixture_1):
print(\"这是fixture_2的【前置】\")
yield 2
print(\"这是fixture_2的【后置】\")
@pytest.fixture()
def fixture_add(fixture_1, fixture_2):
print(\"这是fixture_add的【前置】\")
yield fixture_1 + fixture_2
print(\'这是fixture_add的【后置】\')
def test_fixture(fixture_2, fixture_add):
print(\"这是测试函数\")
assert fixture_add == 3
\"\"\"
执行结果
fixture/yiled_order.py::test_fixture 这是fixture_1
这是fixture_2的【前置】
这是fixture_add的【前置】
这是测试函数
PASSED这是fixture_add的【后置】
这是fixture_2的【后置】
\"\"\"
(二)使用addfinalizer关键字实现后置
- request.addfinalizer把函数变成终结器实现后置处理
import pytest
@pytest.fixture()
def fixture_1(request):
print(\"这是fixture_1的【前置】处理\")
def addfinalizer_demo():
print(\"这是fixture_1的【后置】处理\")
# 注册后置处理
request.addfinalizer(addfinalizer_demo)
def test_fixture(fixture_1):
print(\"===这是测试函数===\")
\"\"\"
执行结果
fixture/use_addfinalizer.py::test_fixture 这是fixture_1的【前置】处理
===这是测试函数===
PASSED这是fixture_1的【后置】处理
\"\"\"
- request.addfinalizer注册多个终结器函数
import pytest
@pytest.fixture()
def fixture_1(request):
print(\"这是fixture_1的【前置】处理\")
def addfinalizer_demo_1():
print(\"这是fixture_1的【后置】处理1\")
def addfinalizer_demo_2():
print(\"这是fixture_2的【后置】处理2\")
# 将多个后置处理函数注册成终结函数
request.addfinalizer(addfinalizer_demo_1)
request.addfinalizer(addfinalizer_demo_2)
def test_fixture(fixture_1):
print(\"=====这是测试函数=====\")
\"\"\"
执行结果
fixture/use_more_addfinalizer.py::test_fixture 这是fixture_1的【前置】处理
=====这是测试函数=====
PASSED这是fixture_2的【后置】处理2
这是fixture_1的【后置】处理1
\"\"\"
- 执行顺序
由上面注册多个终结器函数示例中可以看到,使用addfinalizer
关键字处理后置函数的执行顺序与注册顺序是反的
(三)yield和addfinalizer的区别
区别在于如果fixture
中前置出现异常,yield
后置不会执行,而addfinalizer
后置会执行。
- 使用
yield
import pytest
@pytest.fixture()
def fixture_yield():
print(\"这是fixture_yield前置\")
res = 21/0
yield
print(\"这是fixtue_yield后置\")
def test_fixture(fixture_yield):
print(\"这是测试函数\")
\"\"\"
执行结果
yield_error.py::test_fixture ERROR [100%]这是fixture_yield前置
test setup failed
@pytest.fixture()
def fixture_yield():
print(\"这是fixture_yield前置\")
> res = 21/0
E ZeroDivisionError: division by zero
yield_error.py:12: ZeroDivisionError
\"\"\"
- 使用
addfinalizer
import pytest
@pytest.fixture()
def fixture_1(request):
print(\"这是fixture_1前置\")
def addfinalizer_demo():
print(\"这是fixture_1后置\")
request.addfinalizer(addfinalizer_demo)
res = 21/0
def test_fixture(fixture_1):
print(\"这是测试函数\")
\"\"\"
执行结果
addfinalizer_error.py::test_fixture ERROR [100%]这是fixture_1前置
test setup failed
request = <SubRequest \'fixture_1\' for <Function test_fixture>>
@pytest.fixture()
def fixture_1(request):
print(\"这是fixture_1前置\")
def addfinalizer_demo():
print(\"这是fixture_1后置\")
request.addfinalizer(addfinalizer_demo)
> res = 21/0
E ZeroDivisionError: division by zero
addfinalizer_error.py:16: ZeroDivisionError
这是fixture_1后置
\"\"\"
从上面yield
和addfinalizer
的示例中可以看出yield
前置中出现异常,后置处理没有被执行,而addfinalizer
的前置中出现异常,并没有影响后置的执行。
注意: 使用addfinalizer
一定是后置函数注册成功后出现异常才不会受影响。
参考:https://zhuanlan.zhihu.com/p/355285675
来源:https://www.cnblogs.com/qishuaiRisen/p/16589328.html
本站部分图文来源于网络,如有侵权请联系删除。