When the average test coverage threshold across multiple modules isn't met, pytest doesn't fail with a non-zero exit code, even though it should.
My command:
❯ pytest --cov module1 --cov module2 --cov module3 --cov-report --cov-fail-under=75
I get the following result:
FAIL Required test coverage of 75.0% not reached. Total coverage: 74.79%
But the exit code remains zero:
❯ echo $?
0
As a result, my CI/CD pipeline passes just fine even though my coverage threshold isn't met. This causes main to have too low test coverage.
I've tried
- Passing
--cov=module1,module2,module3instead of having one pytest call with three different--covarguments. This causes the coverage report to fail altogether, because it says thatCoverageWarning: Module module1,module2,module3 was never imported. I.e., it tries to importmodule1,module2,module3as a single module and it fails, since they are separate modules. - Passing the to-be-included modules in
pyproject.tomlunder[tool.coverage.run]in theincludeargument. Problem persists: test coverage threshold failure is noted, but exit code is zero. - Interestingly, when you test on each of the modules individually, you do get a non-zero exit code for the module that has too low coverage.
- On the internet, I can't really seem to find a working solution. Copilot isn't very useful here either.
py2lcovtool from thelcovpackage, to convert your Coverage.py data to lcov format - then uselcovto aggregate and report on the result. Similarly, once converted, you can use tehgenhtmltool to produce a navigable report. Seepy2lcov --helpand thelcovand 'genhtml` man pages for details. The.../tests/py2lcov/testcase shows some sample usage.