Recently, when switching from Coveralls to Codecov coverage in my project dropped by a few percent. This seems to be due to partial hits, which are counted as hits in Coveralls but as misses in Codecov.
Here is a code example:
class Struct(object): # hit
def __init__(self, content=None): # hit
if content is not None: # partial hit
self.content = content # missed
s = Struct() # hit
As far I see, the if statement is fully evaluated by the interpreter. Why is it not counted as a hit, then?
It means that on that line there is a branching statement but one of the branches was never executed.
From the following line, it is obvious that the content was not ever given to that constructor, so you never tested the code with Struct(content=something)
.
Note also that if you do not give an argument, self.content
will not be set, and thus AttributeError
will be raised if access is attempted.
While in this case you could deduce it from the statement inside if
, were the truth value opposite, you couldn't see that the condition was never false. Consider your example again, slightly modified
class Struct(object): # hit
def __init__(self, content=None): # hit
if content is not None: # partial hit
self.content = content # hit
def print_content(self): # hit
print(self.content) # hit
s = Struct('42') # hit
s.print_content() # hit
Looks like everything is fine? If you didn't use branch coverage, the if
would also say "hit", and you wouldn't notice that you never tested the code in the case that content is not None
is False
, which then would have the bug of not setting the self.content
attribute: the following program:
s = Struct()
s.print_content()
when run, raises:
Traceback (most recent call last):
File "foo.py", line 10, in <module>
s.print_content()
File "foo.py", line 7, in print_content
print(self.content)
AttributeError: 'Struct' object has no attribute 'content'
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With