Code


Version 8 (modified by nielsw, 5 years ago) (diff)

--

Django Testing Guide

Testing web applications has historically been hard. It's even harder to write unit tests that work well when someone integrates your app. This guide aims to provide pointers and best practices for testing your apps and writing portable unit tests.

Though there are multiple types of automated tests, this article deals with unit tests. Unit testing is often combined with test-driven development. This means you write your test first and then implement code to make the test pass. The basic workflow is:

  1. Write the test case
  2. Run the test case (to make sure it fails)
  3. Write the implementation code
  4. Run the test case (to make sure it passes)

Writing portable tests

Portable tests, like portable software, are tests that will run properly regardless of how the and where the test code is executed. It could be your app will be ran standalone or integrated in a bigger project.

tests should run in isolation

Whenever possible use test_urls and dedicated test templates to make sure your tests run as isolated. Usually you will want to write your test in such a way that they will only fail when there a failure in what you're testing. What you don't want is your unit tests failing because someone decided to put a bad template tag in your non-test template.

If at all possible you should avoid using Django's test client, too. Why? Because it often introduces failures which are not related to your code (e.g. middleware). If you're going to do anything more complex than getting or setting a variable in Django, write a method class to do that and test it directly.

tests should test one thing

A good test tests one thing, not five or ten. If you have multiple

test_urls

Never use test_urls if your don't have a dedicated test template. Someone else may insert {% url %} tags in there (or template tags that do url reversing) causing your unit tests to fail.

Solving specific problems

Testing view classes

Testing view classes through the test.client() can often require you to write lots of views that call the test class. It's often convenient to write a mapper view class that allows you to map a function to a temporary url.

Other pages about testing and django

CookBookTestingTools describes test runners like nose