Pytest中两个function作用域fixture清理顺序异常问题咨询
问题分析与解决
核心原因:pytest fixture的清理执行顺序是反向的
pytest中,fixture的setup阶段按测试函数参数的顺序执行,但清理阶段(yield后的代码)是按setup的反向顺序执行。
你的场景里:
- 测试函数
test_1的参数顺序是appclient, cleanup_1, cleanup_2 - Setup阶段执行顺序:
- 先初始化session级的
appclient(整个测试会话仅执行一次) - 接着执行
cleanup_1的setup(你这里yield前无代码,所以跳过) - 最后执行
cleanup_2的setup(同样yield前无代码)
- 先初始化session级的
- 测试函数执行完成后,清理阶段按setup的反向顺序执行:
- 先执行
cleanup_2的yield后代码 - 再执行
cleanup_1的yield后代码
这就是你看到cleanup_2总是先执行清理的原因。
- 先执行
为什么改成module级作用域会恢复正常?
当你把cleanup_2的作用域改为module后:
cleanup_2的setup会在module内第一个测试前执行,清理则在module内所有测试完成后执行- 而
cleanup_1是function级,每个测试后都会执行清理 - 此时清理顺序变成:先执行function级的
cleanup_1清理,再执行module级的cleanup_2清理,符合你预期的顺序。
关于“无setup代码的fixture被当作setup使用”的疑问
pytest的fixture不管yield前有没有代码,都会被纳入setup流程:
- 即使yield前没有任何逻辑,pytest依然会在测试函数执行前“走过”这个fixture的yield点,完成setup阶段的调用
- 这是fixture的固有机制,保证依赖链的完整性,也确保清理代码能在正确时机触发。
如何让function级的两个清理fixture按预期顺序执行?
如果你想让cleanup_1的清理先执行,cleanup_2的清理后执行,只需要调整测试函数的参数顺序,把cleanup_2放在cleanup_1前面:
def test_1(appclient, cleanup_2, cleanup_1): # 测试逻辑
这样setup阶段先执行cleanup_2,再执行cleanup_1,清理阶段就会先执行cleanup_1的代码,再执行cleanup_2的代码。
内容的提问来源于stack exchange,提问作者cmdulek98
相关产品推荐
相关产品推荐

