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?
I had the same problem using a remote interpreter in a virtual machine through the ssh configuration. The solution was to set my tests directory and ALL its parent directories in the "Path mappings" of the "Environment" section of "Run" > "Edit Configurations...".
I've managed to get this working including a
on top of my manage.py file (I'm using Flask instead but having the very same issue)
My problem is that it works from console but Jenkins is not aware of it and keeps on saying that those imports are out of the tests...
Any idea?
As the docs say, "use the command line to run your program with coverage":
I spent sometime with this problem, and even with the answers given, they were not detailed enough to fully explain what I was experiencing. Here is what works well for me now, as per answer from iyn with a few necessary tweaks. My manage.py looks like this:
As can be seen above, I included all my apps for testing and excluded where I keep my integration tests.
My
settings.py
I dropped using cover package andwith-coverage
as this is already handled inmanage.py
now. Here is my settings with some explanations:I run my basic tests like so (with coverage):
And now I can see models.py, admins.py as well as apps.py gets covered.
I run my integration tests like so (without coverage):
I can also run a specific set of tests like so:
You can also modify
NOSE_ARGS
as you wish or leave it out completely if you intend to use the flags each time on the command line. Cheers!At the moment it's not possible to accurately run coverage alongside with django-nose (because of the way Django 1.7 loads models). So to get the coverage stats, you need to use coverage.py directly from command line, e.g:
You can put coverage.py settings into .coveragerc file in the project root (the same dir as manage.py).
This issue is reported on django-nose GitHub page: https://github.com/django-nose/django-nose/issues/180 so maintainers know about the problem, you can let them know that you're also experiencing this issue.
UPDATE
eliangcs pointed out (django-nose issues on GiHub), that woraround is to modify your
manage.py
:It works, but it's rather "hacky" approach.
UPDATE 2
I recommend for everybody that uses nose to have a look at py.test (http://pytest.org/), which is really good Python testing tool, it integrates well with Django, has a lot of plugins and many more. I was using django-nose, but tried py.test and never looked back.