You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
I have code that contains branches that are provably executed from output but show up in the coverage as missing. Working with the pytest-cov folks, I reduced the problem to a very simple yet verbose group of unit tests.
There are 4 tests (foo to foobar inclusive) that test the branch detection and coverage. All of the functions are the same with additional yet fixed complexity wrapping them. foo() is the basic if block. fooa() is an if block with the foo() if block contained within it. Other complexity is added (the for block seems to break things) to make the test fairly complete.
Ideally, the coverage should be 100% since it is basically the same if block. However, the ideal case is not the result. There are then sna() and snafu() that have changed the basic if block to if-else blocks and they do pass.
Here is the command line to run the test: python3 -m pytest --cov=cov_test --cov-branch --cov-report term-missing PyScripts/cov_test.py
It produces these results:
============================= test session starts ==============================
platform linux -- Python 3.5.2, pytest-3.1.3, py-1.4.34, pluggy-0.4.0
rootdir: /home/niessner, inifile:
plugins: cov-2.5.1
collected 1 item s
PyScripts/cov_test.py .
----------- coverage: platform linux, python 3.5.2-final-0 -----------
Name Stmts Miss Branch BrPart Cover Missing
-------------------------------------------------------------------
PyScripts/cov_test.py 48 0 20 2 97% 18->21, 27->30
=========================== 1 passed in 0.03 seconds ===========================
Here is the test module:
def foo(states:[bool]):
if all(states):
print ('foo')
pass
return True
def foob (states:[bool]):
if True:
if all(states):
print ('foob')
pass
pass
return True
def fooba (states:[bool]):
for i in range(10):
if all(states):
print ('fooba')
pass
pass
return True
def foobar (states:[bool]):
if True:
for i in range(10):
if all(states):
print ('fooba')
pass
pass
pass
return True
def sna (states:[bool]):
for i in range(10):
if all(states):
print ('sna')
else: print ('ans')
pass
return True
def snafu (states:[bool]):
if True:
for i in range(10):
if all(states):
print ('snafu')
else: print ('ufans')
pass
pass
return True
def test():
assert foo([True,False])
assert foo([True,True])
assert foob([True,False])
assert foob([True,True])
assert fooba([True,False])
assert fooba([True,True])
assert foobar([True,False])
assert foobar([True,True])
assert sna([True,False])
assert sna([True,True])
assert snafu([True,False])
assert snafu([True,True])
return
This is because lines 21 and 30 are "pass", which are optimized away by the Python compiler. If you change those lines to something with an effect (a = 1), the coverage will go to 100%.
Unfortunately, Python doesn't have an option to completely disable the peephole optimizer, so there is no way to keep them. Comment on Python bug 2506 if you feel strongly about it: http://bugs.python.org/issue2506
Originally reported by Anonymous
See pytest-cov for history.
I have code that contains branches that are provably executed from output but show up in the coverage as missing. Working with the pytest-cov folks, I reduced the problem to a very simple yet verbose group of unit tests.
There are 4 tests (foo to foobar inclusive) that test the branch detection and coverage. All of the functions are the same with additional yet fixed complexity wrapping them. foo() is the basic
if
block. fooa() is anif
block with the foo()if
block contained within it. Other complexity is added (thefor
block seems to break things) to make the test fairly complete.Ideally, the coverage should be 100% since it is basically the same
if
block. However, the ideal case is not the result. There are then sna() and snafu() that have changed the basicif
block toif-else
blocks and they do pass.Here is the command line to run the test:
python3 -m pytest --cov=cov_test --cov-branch --cov-report term-missing PyScripts/cov_test.py
It produces these results:
Here is the test module:
The text was updated successfully, but these errors were encountered: