jeudi 27 février 2020

How to find code which was never executed in coverage.py despite a 100% coverage report

Consider the following code:

import math

def dumb_sqrt(x):
    result = math.sqrt(x) if x >= 0 else math.sqrt(-x)*j
    return result


def test_dumb_sqrt():
    assert dumb_sqrt(9.) == 3.

The test can be executed like this:

$ pip install pytest pytest-cov
$ pytest test_thing.py --cov=test_thing --cov-report=html --cov-branch

The coverage report will consider all lines 100% covered, even with branch coverage enabled:

inline

However, this code has a bug, and those of you with a keen eye may have seen it already. Should you ever go into the "else" branch, there will be an exception:

NameError: global name 'j' is not defined

It's easy to fix the bug: change the undefined j name into a literal 1j. It's also easy to add another test which will reveal the bug: assert dumb_sqrt(-9.) == 3j. Neither is what this question is asking about. I want to know how to find sections of code which were never actually executed despite a 100% code coverage report.

Using conditional expressions is one such culprit, but there are similar cases anywhere that Python can short-circuit an evaluation (x or y, x and y are other examples).

Preferably, the line 4 above could be colored as yellow in the coverage report, similar to how the "if" line would have been rendered if you did not use an inline conditional expression in the first place:

long

Does coverage.py support such a feature? If so, how can you enable "inline branch coverage" in your cov reporting? If not, are there any other approaches to identify "hidden" code that was never actually executed by your test suite?

Aucun commentaire:

Enregistrer un commentaire