Tools for Testing in Django: Nose, Coverage and Factory Boy

In this post, you will learn how to install and use Nose, a tool for running your tests in Django.
You’ll learn how to run and configure Coverage, so that it reports only the packages and directories of interest.
And also, you’ll learn how to install and use Factory Boy in your tests (an alternative to Fixtures).

If you want to learn more about testing, check this post about Django testing: Doctests and Unittests.

First of all, why test with Nose?

These are some of the reasons why you should try Nose for testing:
  • Extends the functionalities of unittest
  • It tests your apps by default, and not all the standard ones that are included in the INSTALLED_APPS of your settings file
  • It detects all the functions and classes that start with Test or test that you have defined in your code, so no more worrying about how can I make my tests visible to the Test Suite?
  • You can test specific apps, folders, files or tests
  • You can use all the nose plugins
  • And much more!! Comment if you think I forgot something important! 😉

Let’s start with Django Nose!

First, activate your testing environment and install nose and django-nose via pip:

$ pip install nose
$ pip install django-nose

don’t forget to add them in your requirements file for the testing environment. Then, add django-nose to the installed apps in your testing file:


Note: if you use South, make sure you include it before django_nose in the installed apps. This is because South installs its own test command that turns off migrations during testing. This way, you make sure that the django_nose’s test command is used.

In case you have a testing settings file that inherits from another settings file that contains all your installed apps, you can add this package by:

from .settings import *
INSTALLED_APPS += (‘django_nose’,)

Finaly, you have to indicate Django to use the Nose test runner. In the test settings file add:

TEST_RUNNER = ‘django_nose.NoseTestSuiteRunner’

Save and make sure everything is installed properly by running

$ python test


If you get an error like “permission denied to create database” check this post on Django testing.

Coverage Library

This library is an amazing tool that tells you which parts of your code are covered by tests. It is nicely integrated with django-nose, so to install it, just run:

$ pip install coverage

Then, you can run coverage with

$ python test –with-coverage

If you want to run your tests with this default behavior, open your test settings file and add the following:

    ‘–cover-package=myapp1, myapp2’,

The second option, –cover-package indicates the packages to cover with coverage. In this case we cover two apps, myapp1 and myapp2 (these names are the ones you use in INSTALLED_APPS). And the third option, –cover-inclusive, indicates coverage to scan all the files in the working directories (this is useful to find files that are not being tested).

After this configuration, then you run

$ python test

only the packages myapp1 and myapp2 will be tested, and you’ll see the corresponding coverage report. However, if you are using South, this report includes all your migration files, and your overall cover score will be affected.

In order to omit these files, create a file in the root directory (at the same level of named .coveragerc and write the following:

omit = ../*migrations*

Run your tests again and you’ll see that the migrations don’t show in the coverage report 🙂

If you change the verbosity displayed in your tests, by adding -v 3

$ python test -v 3

you’ll see that every time you run the tests, a new database is created and then all the South fixtures are applied. This can take some time, so if you want to prevent this from happening, there are two different ways:

  • Create and reuse a database for testing. With this method, you can create a database for testing, and instead of deleting it when all the tests are done, it remains there to be reused every time the tests are run. You can find more information in this post.
  • Disable South migrations in your tests. With this method, when the database is created, instead of running migrate in the apps managed by South, it runs directly syncdb. To use this method, open the file you use for testing and add:

          SOUTH_TESTS_MIGRATE = False

Now your tests will run faster!

Factory Boy

As recommended by the 2 Scoops of Django book (amazing Best practices book!) fixtures are hard to maintain as the project evolves and data structures change. One alternative they recommend is the library factory_boy, which helps in the creation of models in your tests.

To install it, use pip:

$ pip install factory_boy

And that’s it! 🙂

Now, let’s look an example of a test that uses some Nose tools and a Factory Model! First, we create a model in

Next, we create the tests for that model:

Note that:

  • We create a model with 3 different mandatory fields: location, rooms and balkon.
  • In the test file, we create the class HouseFactory, which creates instances of a House every time is called.
  • By default, HouseFactory creates a house in Barcelona with 3 rooms. But as balkon does not have any default value, we need to specify it when we create the new instance.
  • We can override any default value by specifying it when a new instance is created.
  • Nose provides extra tools for testing. Here we show the function eq_, which may not be very interesting, as it is equivalent to assertEqual… 🙂 Check out other functions in here.
  • And check out the extra tools for testing that provides django-nose here.

Detect Test mode in your functions

Sometimes, you might want to execute a custom function when you’re in the testing environment. For example, when doing API calls.

In order to detect whether you’re in a testing environment, you can introduce a variable in your file:

import sys
TESTING = ‘test’ in sys.argv

so that the variable TESTING will be true when the command line arguments include the word test.

Then, you can call this variable from anywhere in your code with

from django.conf import settings
if settings.TESTING:

Now it’s time you create your tests!

+1 if this was helpful! 😉


Please, add +Marina Mele in your comments. This way I will get a notification email and I will answer you as soon as possible! :-)