I often find myself testing that the queryset returned by a method contains the instances I expect. I use a custom method, **assertQuerysetEqual()**, to test the equality of two querysets or lists::
def test_some_values(self):
qs = get_user_list()
self.assertQuerysetEqual(qs, [normal_user, super_user])
Makes it easy to test small querysets against lists whose values are known and expected.
Add `FakeSSLMiddleware` to the top of your `MIDDLEWARE_CLASSES` stack when running tests or developing locally to allow https:// links to operate correctly. Can be used in conjunction with other SSL middleware to allow critical tests to be performed.
Django loads tests found in models.py and tests.py (if present) or actually a module or package named 'tests' under the app. Since tests can be a package, one can create a 'tests' directory, split the test cases across multiple files under 'tests' and import them from tests/__init__.py with:
# tests/__init__.py
from test_mod1 import *
from test_mod2 import *
...
from test_modN import *
For a small number of files that's not too bad but it gets old as more files are added, plus it is error prone (e.g. test cases shadowing others with the same name). The snippet above simplifies the test splitting without importing everything into the same namespace.
Typical usage:
# tests/__init__.py
from ... import get_suite
suite = lambda: get_suite(__name__)
By using this simple wrapper instead of Django's default send_mail function, you gain the peace of mind of knowing that when settings.DEBUG == True, all the emails will be sent to you instead of the original recipient. Handy for testing.
In test code, it is sometimes useful to monkeypatch a Django method to have stubbed out behavior, so that you can simplify data setup. Even with decent data setup you might want to avoid execution of Django code that is not the target of your test.
The code snippet shown here illustrates a technique to limit the scope of your monkeypatches. It uses the Python "with" statement, which was introduced in 2.5.
[with statement](http://effbot.org/zone/python-with-statement.htm)
The key aspect of the "with" machinery is that you can set up an __exit__ method that gets called even if the code inside the "with" raises an exception. This guarantees that your monkeypatch gets un-monkeyed before any other code gets called.
I don't recommend monkeypatches in production, but if you HAVE to resort to a monkeypatch, I definitely advise using "with" to limit their scope.
The examples on the left illustrate how to suppress versions of reverse() and timesince()--look at the import statements to see which ones I am talking about. Obviously, monkeypatching is not for the faint of the heart, as you need to be able to find the code to monkeypatch in Django source, and you need to be sure there aren't decorators at play.
This command, `runtester` will run the test suite whenever files are modified. It takes the apps to test as arguments; if no apps are given the entire test suite is run.
Use this command just as `runserver` is used; fire it up in a shell and it does its thing.
Copy this snippet into `django/core/management/commands/runtester.py`.
The "testdata" tag allows you to inline test data into your templates, similar in spirit to Python doctests. There are two sections--the test data and the actual template to be rendered. In non-test mode your template renders normally from whatever views call it, and there is very little overhead to skip over the test data section (happens at parse time).
Here are the goals:
1. Provide convenient way to test templates without surrounding infrastructure.
2. Make templates be self-documenting in terms of expected data.
3. Allow insertion of test data at arbitrary places in template structure.
Hello-world looks like this:
{% load handytags %}
{% testdata %}
{
'greeting': 'Hello',
'planet': 'World',
}
{% --- %}
{# This is where the actual template begins #}
{{ greeting }} <b>{{ planet }}</b>
{% endtestdata %}
To invoke it, set up urls.py with something like this:
url(r'^testdata/(?P<template_path>.*)', test_template)
def test_template(request, template_path):
context = {'testdata_use': True}
# put request vars into context to help choose
# which test data we want to render
for field in request.GET:
context[field] = request.GET[field]
return render_with_request(template_path, context, request)
Then call:
http://127.0.0.1:8000/testdata/hello_world.html
Features:
1. The testdata tag's rendering will expose missing variables a bit more aggressively than Django normally does.
2. You have the full power of the template language to set the test data (which ultimately gets eval'ed as a Python expression).
3. As mentioned above, the tag is mostly unobtrusive.
Limitations/caveats:
1. Right now the only data format I support is pure Python, but the tag could be modified pretty easily to support JSON or YAML.
2. The VerboseContext class is pretty heavy-handed--I really just want a hook into Django to tell it to render a section with more strictness about variables. Suggestions welcome.
3. You can put the testdata tag pretty much anywhere, but the normal rules apply...for example, if you are in a template that has the extend tag, you'll want
to put the testdata tag in individual blocks.
I wanted to use Nose with Django so I came up with this.
`TEST_RUNNER = 'noserun.run_tests'` in settings.py
It does not do setup/teardown implicitly between test
methods, you need to call *nosetest.test.flush()* and
*nosetest.test.loaddata()* manually if you want that.
Enables the method names *setup* and *teardown*
The environment variable *NOSE_COVER* runs coverage
tests and *NO_DROPDB* preserves the test db.
http://steven.bitsetters.com/articles/2009/03/09/testing-email-registration-flows-in-django/
Testing email registration flows is typically a pain. Most of the time I just want to sign up with a test user, get the email link and finish the flow. I also want to be able to automate the whole process without having to write some SMTP code to check some mail box for the email.
The best way I’ve found to do this is just to write out your emails to some file instead of actually sending them via SMTP when your testing. Below is some code to do just that. I’ve also created a Django management script that will open the last email sent out from your application, find the first link in it and open it in your web browser. Quite handy for following email registration links without logging into your email and clicking on them manually.
In-browser testing frameworks (I'm using [Windmill](http://www.getwindmill.com/)) have trouble testing file uploads because javascript's security policy prevents them from setting the value of file input fields. Instead the tests must issue some sort of "fake" file upload request, but implementing this on an ad-hoc basis quickly gets ugly.
This middleware is designed to support fake file uploads as transparently and as thoroughly as possible. For example, it is careful to properly trigger any file upload handlers so that things like upload progress reporting will work correctly. It can also simulate a slow file upload by sleeping between reads from the file.
From the client-side point of view, each input field of type "file" has a similarly-named hidden field automatically prepended. Test scripts can simply set the value of this hidden field to trigger a fake upload, rather than having to set the value of the file input field itself.
This is a small addition to the mako template processing plugin for django that allows you to use the unit test framework with mako templates. To install, put the code into a file on your python path, and add the python path to your settings.py file. For example, if you install the code at
/usr/lib/python2.5/site-packages/mako_django/test_integration.py
you would add the following line to settings.py:
TEST_RUNNER="mako_django.test_integration.run_mako_tests"
This code will still call all of the normal test code, it just adds the mako template handler onto the list of things that are monitored.
Sometimes you need to test some model features without a complete django app installation. Just play only with the model object. With these small script you have a complete in memory django installation.
Some Links:
http://www.djangosnippets.org/snippets/1044/ (en)
http://www.jensdiemer.de/permalink/150/mein-blog/99/django-db-model-test/ (de)
http://www.python-forum.de/viewtopic.php?f=3&t=15649 (de)
See also:
https://github.com/readevalprint/mini-django/
This is a simple fixture that is useful for many tests.
It contains the following users:
* admin
* staff
* user0
* user1
* user2
* user3
* inactive0
* inactive1
The password of every user is the same as his username, e.g.: admin/admin
Django's testing framework assumes you will be running your tests against "live" views that have been plugged in to your site's URL configuration - but sometimes you might want to run a test against a view function without first wiring it in to the rest of the site. This class makes it easy to do that by providing a "factory" for creating mock request objects, re-using the existing test Client interface (and most of the code). Once you've created a request object in your test you can use it to call your view functions directly, then run assertions against the response object that gets returned.
While we're on the topic of SSLRedirect (See snippet 240 and 880) here's what I add to the end of my ssl middleware module, so that SSLRedirect wont break my automated testing.
It simply creates a dummy middleware class that removes the SSL argument, but does not do any redirecting. If you were to simply remove the middleware from settings, the extra SSL argument will then get passed on to all the relevant views.
Of course, you'll need to define a TESTING variable in settings, or change this to something else like settings.DEBUG. Having the separate variable for testing allows you to run your server in DEBUG mode without side effects like the change above.