Reputation: 61
Test marks the code as covered if the condition is 0 but as uncovered if the condition is a variable with value of zero.
I was trying a simple thing in pytest with coverage and I found this bug (?). I am not sure if I am missing something in how pytest or python works.
Here bellow is my function
def dummy_func(a=0):
if a:
print('this part is not tested !!')
else:
print('this part is tested !!')
if 0: # tried None as well
print('this part is not tested, but appears like it is !')
else:
print('this part is tested !!')
return 1
and this is the report I got
---------- coverage: platform linux, python 3.10.6-final-0 -----------
Name Stmts Miss Cover Missing
------------------------------------------------------
myproject/flask_api.py 7 1 86% 4
tests/test_hello.py 4 0 100%
------------------------------------------------------
TOTAL 11 1 91%
Should not the line under the if 0 be marked as Miss. Is that a bug or I am missing something ?
I got that in both version
pytest-cov = "4.0.0" and "3.0.0" also with coverage
my test code is that
from myproject import flask_api
def test_dummy():
result = flask_api.dummy_func()
assert result == 1
Upvotes: 1
Views: 1053
Reputation: 12140
So the answer to your question is that it's not a bug, it's expected behavior.
From the coverage.py
docs:
After your program has been executed and the line numbers recorded, coverage.py needs to determine what lines could have been executed. Luckily, compiled Python files (.pyc files) have a table of line numbers in them. Coverage.py reads this table to get the set of executable lines, with a little more source analysis to leave out things like docstrings.
and
The data file is read to get the set of lines that were executed. The difference between the executable lines and the executed lines are the lines that were not executed.
and
The same principle applies for branch measurement, though the process for determining possible branches is more involved. Coverage.py uses the abstract syntax tree of the Python source file to determine the set of possible branches.
That is just how coverage.py
works. It does not consider unreachable code in its report. It doesn't mark it as missed but it doesn't mark it as tested either.
For instance, here is how the report looks in PyCharm (note the unmarked line 7):
Some more examples:
Interestingly enough, PyCharm can't evaluate 'a' * 0
as "always falsy" but can evaluate 'a'.replace('a', '')
as such, while coverage.py
does the opposite.
Upvotes: 4