Index: django/test/testcases.py =================================================================== --- django/test/testcases.py (revision 7974) +++ django/test/testcases.py (working copy) @@ -1,4 +1,6 @@ import re +import os +import sys import unittest from urlparse import urlsplit, urlunsplit @@ -58,6 +60,11 @@ named fixtures. * If the Test Case class has a 'urls' member, replace the ROOT_URLCONF with it. + * If the Test Case class has a 'template_dirs` member, replace the + TEMPLATE_DIRS with the values in template_dirs interpreted as + path names relative to the directory where the test is defined. + * If the Test Case class has a 'template_loaders` member, replace the + TEMPLATE_LOADERS with it. * Clearing the mail test outbox. """ call_command('flush', verbosity=0, interactive=False) @@ -69,6 +76,14 @@ self._old_root_urlconf = settings.ROOT_URLCONF settings.ROOT_URLCONF = self.urls clear_url_caches() + if hasattr(self, 'template_loaders'): + self._old_template_loaders = settings.TEMPLATE_LOADERS + settings.TEMPLATE_LOADERS = self.template_loaders + if hasattr(self, 'template_dirs'): + self._old_template_dirs = settings.TEMPLATE_DIRS + test_dir = os.path.dirname(sys.modules[self.__module__].__file__) + settings.TEMPLATE_DIRS = [ os.path.join(test_dir, dirname) for dirname in self.template_dirs ] + mail.outbox = [] def __call__(self, result=None): @@ -104,6 +119,10 @@ if hasattr(self, '_old_root_urlconf'): settings.ROOT_URLCONF = self._old_root_urlconf clear_url_caches() + if hasattr(self, '_old_template_loaders'): + settings.TEMPLATE_LOADERS = self._old_template_loaders + if hasattr(self, '_old_template_dirs'): + settings.TEMPLATE_DIRS = self._old_template_dirs def assertRedirects(self, response, expected_url, status_code=302, target_status_code=200, host=None): Index: django/contrib/auth/tests/basic.py =================================================================== --- django/contrib/auth/tests/basic.py (revision 7974) +++ django/contrib/auth/tests/basic.py (working copy) @@ -61,7 +61,9 @@ class PasswordResetTest(TestCase): fixtures = ['authtestdata.json'] urls = 'django.contrib.auth.urls' - + template_dirs = ('templates',) + template_loaders = ('django.template.loaders.filesystem.load_template_source',) + def test_email_not_found(self): "Error is raised if the provided email address isn't currently registered" response = self.client.get('/password_reset/') Index: django/contrib/auth/tests/templates/registration/password_reset_form.html =================================================================== --- django/contrib/auth/tests/templates/registration/password_reset_form.html (revision 0) +++ django/contrib/auth/tests/templates/registration/password_reset_form.html (revision 0) @@ -0,0 +1 @@ +{% if form.email.errors %}{{ form.email.errors }}{% endif %} \ No newline at end of file Index: django/contrib/auth/tests/templates/registration/password_reset_email.html =================================================================== --- django/contrib/auth/tests/templates/registration/password_reset_email.html (revision 0) +++ django/contrib/auth/tests/templates/registration/password_reset_email.html (revision 0) @@ -0,0 +1 @@ +
A valid email address was provided for password reset
\ No newline at end of file Index: docs/testing.txt =================================================================== --- docs/testing.txt (revision 7974) +++ docs/testing.txt (working copy) @@ -830,6 +830,46 @@ This test case will use the contents of ``myapp.test_urls`` as the URLconf for the duration of the test case. +Test templates +~~~~~~~~~~~~~~ + +**New in Django development version** + +If you are building a truly reusable application, you can't always rely +upon the fact that the project in which your application is deployed will +provide templates in the same way as templates being available. + +In order to provide a reliable collection of templates for your tests, +``django.test.TestCase`` provides the ability to customize the template +directories and loaders for the duration of a test suite. + +If your ``TestCase`` instance defines the attributes ``template_dirs`` +or ``template_loaders``, the values provided will override the values for +``settings.TEMPLATE_DIRS`` and ``settings.TEMPLATE_LOADERS`` respectively, +for the duration of the tests. + +The value of ``template_loaders`` is interpreted the same way that +``settings.TEMPLATE_LOADERS`` is interpreted in a normal settings file. +However, in order to avoid a dependency on a specific absolute project +directory, the directories named in ``template_dirs`` will be interpreted +as being relative to the directory containing the file in which the test +case is defined. + +For example, consider the following test case:: + + from django.test import TestCase + + class TestMyViews(TestCase): + template_dirs = ('templates',) + template_loaders = ('django.template.loaders.filesystem.load_template_source',) + + def testIndexPageView(self): + # Here you'd test your view using ``Client``. + +If this test case was defined in ``/foo/bar/tests/mytest.py``, then templates +would be loaded from ``/for/bar/tests/templates/`` for the duration of the +test case. + Emptying the test outbox ~~~~~~~~~~~~~~~~~~~~~~~~