You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

求助:pytest-cov检测多模块覆盖率未达阈值时返回0退出码的问题

求助:pytest-cov检测多模块覆盖率未达阈值时返回0退出码的问题

我最近碰到了pytest-cov的一个离谱问题:当多个模块的平均测试覆盖率没达到设定阈值时,控制台明明会输出"未达标"的提示,但pytest居然返回0退出码,直接导致我的CI/CD流水线通过,把低覆盖率的代码合并到主分支了,这可太坑了!

先讲下我的具体场景:
我执行的命令是:

pytest --cov module1 --cov module2 --cov module3 --cov-report term --cov-fail-under=75

控制台会正确输出覆盖率未达标的提示:

FAIL Required test coverage of 75.0% not reached. Total coverage: 74.79%

但紧接着执行echo $?,得到的结果却是0——完全没触发CI的失败机制。

我已经试过好几种方案,都没能解决问题:

  • 尝试把多个模块合并成一个参数--cov=module1,module2,module3,结果直接报错CoverageWarning: Module module1,module2,module3 was never imported,它把逗号分隔的内容当成了单个模块名,根本识别不了是三个独立模块。
  • 把需要检测的模块列表写到pyproject.toml[tool.coverage.run]include字段里,结果还是老样子:控制台提示未达标,但退出码依旧是0。

有意思的是,如果单独对每个模块跑测试,比如只测module1,只要它的覆盖率不够,pytest会正常返回非0退出码,完全没问题。

我在网上搜了一圈,没找到能解决的方案,Copilot给的建议也没什么用。


更新:已复现问题,找到疑似根源

我做了一个最小可复现示例(MWE),终于发现问题出在覆盖率的四舍五入逻辑上!

比如我设置阈值为67%,实际总覆盖率是66.66%,控制台会正确提示:

FAIL Required test coverage of 67% not reached. Total coverage: 66.67%

但退出码居然还是0!看起来pytest-cov的退出码判断逻辑,可能是用了四舍五入后的整数覆盖率来和阈值比较——比如66.66%四舍五入后是67%,刚好等于阈值,就返回了0?这完全是逻辑bug啊!

有没有大佬遇到过这个问题?或者知道怎么解决吗?

火山引擎 最新活动