如何在Pytest所有测试完成后基于共享fixture运行最终校验测试
pytest全测试会话结束后调用fixture执行断言的解决方案
你要实现的「所有测试运行结束后基于共享fixture做断言」的需求,可以通过session级自动生效fixture + yield语法实现,完全不需要依赖atexit、session_finish hook等无法访问fixture上下文的方案,实现代码如下:
import pytest # 全局共享存储列表,scope设为session保证整个测试会话唯一实例 @pytest.fixture(scope="session") def fxtr_test_list(): return [] def test_something_1(fxtr_test_list): fxtr_test_list.append(1) def test_something_2(fxtr_test_list): fxtr_test_list.append(2) # session级自动生效fixture,不需要显式被测试用例引用 @pytest.fixture(scope="session", autouse=True) def global_check(fxtr_test_list): # 会话启动、测试执行前的初始校验 assert len(fxtr_test_list) == 0 # yield分割fixture的初始化和销毁逻辑 yield # 所有测试用例执行完成后、任意fixture销毁前执行的最终校验 assert 1 in fxtr_test_list assert 2 in fxtr_test_list assert len(fxtr_test_list) == 2
方案说明
- 用
autouse=True修饰的session级fixture会在测试会话启动时自动触发,不需要在测试用例中手动声明依赖 - yield之前的代码在测试执行前运行,yield之后的代码在所有测试完成后、所有fixture销毁前运行,此时所有fixture的状态都完整保留,可以正常调用任意fixture的内容
- 该位置的断言属于正式测试逻辑的一部分,断言失败会直接判定测试会话失败,输出普通的断言报错信息,不属于teardown清理逻辑
如果你的校验逻辑是module维度的,只需要把fxtr_test_list和global_check的scope改为module即可,会在每个模块的测试用例执行完成后自动触发校验。
原有方案问题说明
你之前检索到的方案存在以下局限性:
atexit是Python进程退出前的钩子,执行时pytest的fixture上下文已经完全销毁,无法访问任何fixture内容- 直接使用
session_finish钩子时,大部分fixture的销毁逻辑已经执行完成,未被特殊引用的fixture已经被回收,无法正常读取状态
内容的提问来源于stack exchange,提问作者komodovaran_
相关产品推荐
相关产品推荐

