Currently have a project configured to run coverage via Django's manage command like so:
./manage.py test --with-coverage --cover-package=notify --cover-branches --cover-inclusive --cover-erase
This results in a report like the following:
Name Stmts Miss Branch BrMiss Cover Missing
--------------------------------------------------------------------------
notify.decorators 4 1 0 0 75% 4
notify.handlers 6 1 2 0 88% 11
notify.notification_types 46 39 2 0 19% 8-55, 59, 62, 66
notify.notifications 51 51 0 0 0% 11-141
--------------------------------------------------------------------------
TOTAL 107 92 4 0 17%
There's a problem with this report however. It's wrong. Coverage is marking lines missing, despite the fact that they are indeed being covered by tests. For example, if I run the tests via nosetests
instead of django's manage command I get the following correct report:
Name Stmts Miss Branch BrMiss Cover Missing
-----------------------------------------------------------------------------
notify.decorators 4 0 0 0 100%
notify.handlers 6 0 2 0 100%
notify.notification_types 46 0 2 0 100%
notify.notifications 51 25 0 0 51% 13, 18, 23, 28, 33, 38, 43, 48, 53, 65, 70, 75, 80, 85, 90, 95, 100, 105, 110, 116, 121, 126, 131, 136, 141
-----------------------------------------------------------------------------
TOTAL 107 25 4 0 77%
Google led me to the coverage website's FAQ, http://nedbatchelder.com/code/coverage/faq.html
Q: Why do the bodies of functions (or classes) show as executed, but the def lines do not?
This happens because coverage is started after the functions are defined. The definition lines are executed without coverage measurement, then coverage is started, then the function is called. This means the body is measured, but the definition of the function itself is not.
To fix this, start coverage earlier. If you use the command line to run your program with coverage, then your entire program will be monitored. If you are using the API, you need to call coverage.start() before importing the modules that define your functions.
The question is, can I run the coverage reports properly via Django's manage command? Or do I have to bypass manage to avoid the situation where coverage is started after the "missing" lines are executed?