You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pytest中两个function作用域fixture清理顺序异常问题咨询

问题分析与解决

核心原因:pytest fixture的清理执行顺序是反向的

pytest中,fixture的setup阶段按测试函数参数的顺序执行,但清理阶段(yield后的代码)是按setup的反向顺序执行。

你的场景里:

  1. 测试函数test_1的参数顺序是appclient, cleanup_1, cleanup_2
  2. Setup阶段执行顺序:
    • 先初始化session级的appclient(整个测试会话仅执行一次)
    • 接着执行cleanup_1的setup(你这里yield前无代码,所以跳过)
    • 最后执行cleanup_2的setup(同样yield前无代码)
  3. 测试函数执行完成后,清理阶段按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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 02:25:54