Search code examples
code-coveragecoverage.pytest-coverage

How is coverage percentage calculated when branch coverage is enabled in coverage.py


I am using coverage.py tool to get coverage of python code. If I use the command without --branch flag like below,

coverage run test_cmd

I get the coverage report like this,

Name                                                                              Stmts   Miss  Cover
--------------------------------------------------------------------------------------------------------------------------
/path/file.py                                                                      9      2    78%

From this I understand that the cover percentage value is derived as this

cover = (Stmts Covered/total stmts)*100 = (9-2/9)*100 = 77.77%

But when I run coverage with --branch flag enabled like this

coverage run --branch test_cmd

I get the coverage report like this,

Name                                                                           Stmts   Miss Branch BrPart  Cover
----------------------------------------------------------------------------------------------------------------------------------------
/path/file.py                                                                    9      2      2      1    73%

From this report I am not able to understand the formula used to get Cover=73%

How is this number coming and is this correct value for code coverage?


Solution

  • While you probably shouldn't worry too much about the exact numbers, here is how they are calculated:

    Reading from the output you gave, we have:

    n_statements = 9
    n_missing = 2
    n_branches = 2
    n_missing_branches = 1
    

    Then it is calculated (I simplified the syntax a bit, in the real code everything is hidden behind properties.)

    https://github.com/nedbat/coveragepy/blob/a9d582a47b41068d2a08ecf6c46bb10218cb5eec/coverage/results.py#L205-L207

    n_executed = n_statements - n_missing
    

    https://github.com/nedbat/coveragepy/blob/8a5049e0fe6b717396f2af14b38d67555f9c51ba/coverage/results.py#L210-L212

    n_executed_branches = n_branches - n_missing_branches
    

    https://github.com/nedbat/coveragepy/blob/8a5049e0fe6b717396f2af14b38d67555f9c51ba/coverage/results.py#L259-L263

    numerator = n_executed + n_executed_branches
    denominator = n_statements + n_branches
    

    https://github.com/nedbat/coveragepy/blob/master/coverage/results.py#L215-L222

    pc_covered = (100.0 * numerator) / denominator
    

    Now put all of this in a script, add print(pc_covered) and run it:

    72.72727272727273
    

    It is then rounded of course, so there you have your 73%.