Installation

Since django-nose extends Django’s built-in test command, you should add it to
your INSTALLED_APPS in settings.py:

INSTALLED_APPS = (
...
'django_nose',
...
)

Then set TEST_RUNNER in settings.py:

TEST_RUNNER = 'django_nose.NoseTestSuiteRunner'

Use

The day-to-day use of django-nose is mostly transparent; just run ./manage.py
test as usual.

See ./manage.py help test for all the options nose provides, and look to
the nose docs for more help with nose.

Enabling Database Reuse

You can save several seconds at the beginning and end of your test suite by
reusing the test database from the last run. To do this, set the environment
variable REUSE_DB to 1:

REUSE_DB=1 ./manage.py test

The one new wrinkle is that, whenever your DB schema changes, you should leave
the flag off the next time you run tests. This will cue the test runner to
reinitialize the test database.

Also, REUSE_DB is not compatible with TransactionTestCases that leave junk in
the DB, so be sure to make your TransactionTestCases hygienic (see below) if
you want to use it.

Enabling Fast Fixtures

django-nose includes a fixture bundler which drastically speeds up your tests
by eliminating redundant setup of Django test fixtures. To use it…

Subclass django_nose.FastFixtureTestCase instead of
django.test.TestCase. (I like to import it as TestCase in my
project’s tests/__init__.py and then import it from there into my actual
tests. Then it’s easy to sub the base class in and out.) This alone will
cause fixtures to load once per class rather than once per test.

Activate fixture bundling by passing the --with-fixture-bundling option
to ./manage.py test. This loads each unique set of fixtures only once,
even across class, module, and app boundaries.

How Fixture Bundling Works

The fixture bundler reorders your test classes so that ones with identical sets
of fixtures run adjacently. It then advises the first of each series to load
the fixtures once for all of them (and the remaining ones not to bother). It
also advises the last to tear them down. Depending on the size and repetition
of your fixtures, you can expect a 25% to 50% speed increase.

Incidentally, the author prefers to avoid Django fixtures, as they encourage
irrelevant coupling between tests and make tests harder to comprehend and
modify. For future tests, it is better to use the “model maker” pattern,
creating DB objects programmatically. This way, tests avoid setup they don’t
need, and there is a clearer tie between a test and the exact state it
requires. The fixture bundler is intended to make existing tests, which have
already committed to fixtures, more tolerable.

Troubleshooting

If using --with-fixture-bundling causes test failures, it likely indicates
an order dependency between some of your tests. Here are the most frequent
sources of state leakage we have encountered:

Locale activation, which is maintained in a threadlocal variable. Be sure to
reset your locale selection between tests.

memcached contents. Be sure to flush between tests. Many test superclasses do
this automatically.

It’s also possible that you have post_save signal handlers which create
additional database rows while loading the fixtures. FastFixtureTestCase
isn’t yet smart enough to notice this and clean up after it, so you’ll have to
go back to plain old TestCase for now.

Exempting A Class From Bundling

In some unusual cases, it is desirable to exempt a test class from fixture
bundling, forcing it to set up and tear down its fixtures at the class
boundaries. For example, we might have a TestCase subclass which sets up
some state outside the DB in setUpClass and tears it down in
tearDownClass, and it might not be possible to adapt those routines to heed
the advice of the fixture bundler. In such a case, simply set the
exempt_from_fixture_bundling attribute of the test class to True.

Speedy Hygienic TransactionTestCases

Background

The default Django TransactionTestCase class can leave the DB in an unclean
state when it’s done. To compensate, TransactionTestCase does a
time-consuming flush of the DB before each test to ensure it begins with a
clean slate. Django’s stock test runner then runs TransactionTestCases last so
they don’t wreck the environment for better-behaved tests. django-nose
replicates this behavior.

Escaping the Grime

Some people, however, have made subclasses of TransactionTestCase that clean up
after themselves (and can do so efficiently, since they know what they’ve
changed). Like TestCase, these may assume they start with a clean DB. However,
any TransactionTestCases that run before them and leave a mess could cause them
to fail spuriously.

django-nose offers to fix this. If you include a special attribute on your
well-behaved TransactionTestCase…

…django-nose will run it before any of those nasty, trash-spewing test cases.
You can thus enjoy a big speed boost any time you make a TransactionTestCase
clean up after itself: skipping a whole DB flush before every test. With a
large schema, this can save minutes of IO.

django-nose’s own FastFixtureTestCase uses this feature, even though it
ultimately acts more like a TestCase than a TransactionTestCase.

Test-Only Models

If you have a model that is used only by tests (for example, to test an
abstract model base class), you can put it in any file that’s imported in the
course of loading tests. For example, if the tests that need it are in
test_models.py, you can put the model in there, too. django-nose will make
sure its DB table gets created.

Assertions

django-nose.tools provides pep8 versions of Django’s TestCase asserts
and some of its own as functions.

Just like middleware or anything else, each string must be a dot-separated,
importable path to an actual class. Each plugin class will be instantiated and
added to the Nose test runner.

Older Versions of Django

Upgrading from Django <= 1.3 to Django 1.4

In versions of Django < 1.4 the project folder was in fact a python package as
well (note the __init__.py in your project root). In Django 1.4, there is no
such file and thus the project is not a python module.

When you upgrade your Django project to the Django 1.4 layout, you need to
remove the __init__.py file in the root of your project (and move any python
files that reside there other than the manage.py) otherwise you will get a
`ImportError: No module named urls` exception.

This means that even though you have set up your directory structure properly and
set your ROOT_URLCONF=’my_project.urls’ to match the new structure, when running
django-nose’s test runner it will try to find your urls.py file in ‘my_project.my_project.urls’.

Upgrading from Django < 1.2

Django 1.2 switches to a class-based test runner. To use django-nose
with Django 1.2, change your TEST_RUNNER from django_nose.run_tests to
django_nose.NoseTestSuiteRunner.

django_nose.run_tests will continue to work in Django 1.2 but will raise a
warning. In Django 1.3, it will stop working.

If you were using django_nose.run_gis_tests, you should also switch to
django_nose.NoseTestSuiteRunner and use one of the spatial backends in
your DATABASES settings.

Django 1.1

Django 1.0

django-nose does not support Django 1.0.

Recent Version History

1.2 (2013-07-23)

Python 3 support (melinath and jonashaag)

Django 1.5 compat (fabiosantoscode)

1.1 (2012-05-19)

Django TransactionTestCases don’t clean up after themselves; they leave
junk in the DB and clean it up only on _pre_setup. Thus, Django makes
sure these tests run last. Now django-nose does, too. This means one fewer
source of failures on existing projects. (Erik Rose)

Add support for hygienic TransactionTestCases. (Erik Rose)

Support models that are used only for tests. Just put them in any file
imported in the course of loading tests. No more crazy hacks necessary.
(Erik Rose)

Make the fixture bundler more conservative, fixing some conceivable
situations in which fixtures would not appear as intended if a
TransactionTestCase found its way into the middle of a bundle. (Erik Rose)

Fix an error that would surface when using SQLAlchemy with connection
pooling. (Roger Hu)

Gracefully ignore the new --liveserver option introduced in Django 1.4;
don’t let it through to nose. (Adam DePue)