Testing - a complete example
The first place to look is the test management command, which Django finds and executes when we run manage.py test. This lives in django.core.management.commands.test. As management commands go, it’s quite short - under 100 lines. Its handle method is mostly concerned with handing off to a a “Test Runner”. # Reuse the test-database (since django version 1.8) $ python manage.py test -keepdb Limit the number of tests executed. It is possible to limit the tests executed by manage.py test by specifying which modules should be discovered by the test runner.
The first problem you’ll run in to when trying to write a test that runs a task is that Django’s test runner doesn’t use the same database as your celery daemon is using. If you’re using the database backend, this means that your tombstones won’t show up in your test database and you won’t be able to get the return value or check. Getting a Django Application to 100% Test Coverage. Code coverage is a simple tool for checking which lines of your application code are run by your test suite. 100% coverage is a laudable goal, as it means every line is run at least once. Coverage.py is the Python tool for measuring code coverage. TESTRUNNER = 'djangonose.NoseTestSuiteRunner' However, this alone doesn’t solve the issue, as Nose test runner looks for the tests the same way as the default Django one. The advantage of.
This assumes that you have read the documentation about starting a new Django project. Let us assume that the main app in your project is named td (short for test driven). To create your first test, create a file named test_view.py and copy paste the following content into it.
You can run this test by
and it will most naturally fail! You will see an error similar to the following.
Why does that happen? Because we haven't defined a view for that! So let's do it. Create a file called views.py and place in it the following code
Next map it to the /hello/ by editing urls py as follows:
Now run the test again ./manage.py test
again and viola!!
Testing Django Models Effectively
Assuming a class
Testing examples
Some points
Django Test Teardown
created_properly
tests are used to verify the state properties of django models. They help catch sitautions where we've changed default values, file_upload_paths etc.absolute_url
might seem trivial but I've found that it's helped me prevent some bugs when changing url paths- I similarly write test cases for all the methods implemented inside a model (using
mock
objects etc) - By defining a common
BaseModelTestCase
we can setup the necessary relationships between models to ensure proper testing.
Finally, when in doubt, write a test. Trivial behavior changes are caught by paying attention to detail and long forgotten pieces of code don't end up causing unnecessary trouble.
Testing Access Control in Django Views
Django Run
tl;dr : Create a base class that defines two user objects (say user
and another_user
). Create your other models and define three Client
instances.
self.client
: Representinguser
logged in browserself.another_client
: Representinganother_user
's clientself.unlogged_client
: Representing unlogged person
Now access all your public and private urls from these three client objects and dictact the response you expect. Below I've showcased the strategy for a Book
object that can either be private
(owned by a few privileged users) or public
(visible to everyone).
The Database and Testing
Django uses special database settings when testing so that tests can use the database normally but by default run on an empty database. Database changes in one test will not be seen by another. For example, both of the following tests will pass:
Fixtures
If you want to have database objects used by multiple tests, either create them in the setUp
method of the test case. Additionally, if you have defined fixtures in your django project, they can be included like so:
By default, django is looking for fixtures in the fixtures
directory in each app. Further directories can be set using the FIXTURE_DIRS
setting:
Let's assume you have created a model as follows:
Then your .json fixtures could look like that:
Reuse the test-database
To speed up your test-runs you can tell the management-command to reuse the test-database (and to prevent it from being created before and deleted after every test-run). This can be done using the keepdb (or shorthand -k
) flag like so:
Limit the number of tests executed
It is possible to limit the tests executed by manage.py test
by specifying which modules should be discovered by the test runner:
If you want to run a bunch of tests you can pass a pattern of filenames. For example, you may want to run only tests that involving of your models:
Finally, it is possible to stop the test suite at the first fail, using --failfast
. This argument allows to get quickly the potential error encountered in the suite: