Django - tests with nose and coverage
The following guide would help us run test using django-nose
. It give us more option to run test either by apps, modules or even just individual tests. We will also include coverage
to give us a test report locally whenever test is run.
First, we installed the required package and update requirements.txt.
$ pip install django-nose
$ pip install coverage
$ pip freeze > requirements.txt
Next, we need to update settings.py
to setup some configuration required by django-nose
.
INSTALLED_APPS = (
...
'django_nose', # Append to INSTALLED_APPS
...
)
TEST_RUNNER = 'django_nose.NoseTestSuiteRunner'
NOSE_ARGS = [
'--cover-erase',
'--cover-package=MY_APP', # Change `MY_APP` to your `app` name
]
Next, we will setup coverage
to display a report whenever python manage.py test
is run. In manage.py
file, update it with this:
if is_testing:
import coverage
cov = coverage.coverage(source=['app'], omit=['*/tests/*'])
cov.set_option('report:show_missing', True)
cov.erase()
cov.start()
# Add this 5 line above
execute_from_command_line(sys.argv)
# and add this 4 line below
if is_testing:
cov.stop()
cov.save()
cov.report()
The code here is asking coverage
to report missing line that is not tested. The reason we are doing this manually instead of using a config file is because of a bug here.
By updating it to the above, whenever python manage.py test
is run, we should see a nice report generated like this:
...................
--------------------------------------------------------------------
Ran 19 tests in 3.564s
OK
Destroying test database for alias 'default'...
Name Stmts Miss Cover Missing
--------------------------------------------------------------------
blog/__init__.py 0 0 100%
blog/admin.py 11 0 100%
blog/apps.py 3 3 0% 1-5
blog/forms.py 6 0 100%
blog/migrations/0001_initial.py 9 0 100%
blog/migrations/0002_postimage.py 7 0 100%
blog/migrations/0003_auto_20170409_1343.py 5 0 100%
blog/migrations/0004_auto_20170410_2116.py 5 0 100%
blog/migrations/__init__.py 0 0 100%
blog/models.py 31 3 90% 9, 37, 45
blog/tests.py 127 0 100%
blog/urls.py 3 0 100%
blog/views.py 65 2 97% 15, 58
--------------------------------------------------------------------
TOTAL 272 8 96%
If we are using CI, we could also generate a html
or xunittest
report. To get a html
report, update the manage.py
file to include this:
cov.save()
cov.html_report(directory='covhtml') # add this line
cov.report()
For generating a xunittest
file, we have to update the NOSE_ARGS
in settings.py to this:
NOSE_ARGS = [
'--cover-erase',
'--cover-package=create_tasksapp',
'--with-xunit', # Add this and the following line
'--xunit-file=xunittest.xml', # xunittest.xml could be any name
]
For more configuration, visit the following page: