This code allows you to register a model to Django that is only used for unit testing.
It will not exist in the regular Django workflow. After the tests executed, the Django settings are restored.
Usage:
1. Change `tests.py` into a `tests` package.
2. Place a `models.py` in the `tests` package.
3. Use the following code below to enable it.
Example:
class MyTest(CustomSettingsTestCase):
new_settings = dict(
INSTALLED_APPS=(
'django.contrib.contenttypes',
'django.contrib.auth',
'app_to_test',
'app_to_test.tests',
)
)
Based on http://djangosnippets.org/snippets/1011/ as Django 1.4 version
This is hardcoded to use [django-discover-runner](http://pypi.python.org/pypi/django-discover-runner) since that's my main test runner but could easily be adopted to use Django's own test runner. If you're using a terminal that is capable of showing 256 colors use the `Terminal256Formatter` formatter instead.
Enabled it with the `TEST_RUNNER` setting:
TEST_RUNNER = 'dotted.path.to.highlighted.runner.HighlightedDiscoverRunner'
Where `dotted.path.to.highlighted.runner` is the Python import path of the file you saved the runner in.
If you want to test for trivial error in your add and changelist admin views, use this snippet.
Save the snippet in admintests.py and put it anywhere in your pythonpath.
Put this code in your tests.py:
from django.test import TestCase
from admintest import adminviews_test
class TestAdminViews(TestCase):
def test_admin_views(self):
adminviews_test(self)
I often insert `pdb.set_trace()` in my test cases to debug and examine behavior. When tests fail with assertions like `assertContains(response, 'Some text')`, it would be useful to see the response's contents in a browser window. This snippet does just that. Simply put this code in a python script on your `PYTHONPATH` and import/call the function when the debugger starts.
Only tested on Ubuntu and you might want to change `URL_OPENER` to whatever you want to open the URLs. Simple, but hopefully useful.
Testing low-level functionality sometimes requires a WSGIRequest object. An example of this is testing template tags.
This will monkey-patch the test Client object to return WSGIRequest objects
Normal Django behavior:
>>> client.get('/')
<HttpResponse >
With this code, get the request object:
>>> client.request_from.get('/')
<WSGIRequest >
Installation:
For this to work, you simply need to import the contents of this file.
If you name this file `clientrequestpatch.py`, do this inside your Django tests.
from django.test.testcases import TestCase
from myproject.test import clientrequestpatch
A coverage test runner that uses the class-based runner introduced with Django 1.2.
Put it in your python path and add to your `settings.py`:
TEST_RUNNER = 'path_to.CoverageRunner'
COVERAGE_MODULES = [
'blog.views',
'projects.views',
'middleware',
]
Compatible with Django 1.2 and higher. You also need Ned Batchelder's `coverage.py` module (`pip install coverage`).
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__)
The inbuilt test client can be used to only test single domain applications ie no support for supplying absolute URLs.
But there are cases where one might like to test against URL rewrites, external domains/services like OpenID, OAuth etc.
This client has an external dependency on httplib2, to maintain the sessions (cookie-based). The API is exactly similar to the inbuilt test client.
>>> from client import TestClient
>>> c = TestClient()
>>> resp = c.get("http://www.google.com/")
>>> resp.status_code
200
**Note**: Unlike the built-in test client, this test client cannot access the template and context attributes from the response even if testing a local application.
Ok... this is really a hack. But I love it. I hate setting up all of my test cases into suites, and making sure that I remember to add them each time I add a new python file... annoying! This allows me to have a tests package and then just add python files and packages to that test package (mirroring my app setup). Each of the files are then dynamically imported and every test case is automatically executed. If you don't want one to execute, add it to the ignore list. If you add 'views' to the ignore list, it will ignore all views, otherwise you would have to specify 'package.views' if it is in a package.
So... in short this is a bit ghetto, but it saves me a lot of time just setting up all my tests... now I can just write them! Hope it's useful to someone.
Greg
Many of my projects heavily depend on other non-django projects to create the databases. To simplify setting up a test environment, I modified the simple test runner so that it will treat all models as managed.
This will also allow for easier test set up against models that point to views. You can directly populate the view with the specific data needed for the tests, instead of populating (potentially) several models.
This class runs a django test server in another thread. This is very useful for e.g. selenium integration. Simple to integrate into django test framework.
Usage:
server = TestServerThread("127.0.0.1", "8081")
server.start()
# Run tests e.g.
req = urllib.urlopen("http://127.0.0.1:8081")
contents = req.read()
server.stop()
ps. I don't actually double space my code :). Not sure whats up with that!