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 @@
+<p>A valid email address was provided for password reset</p>
\ 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
 ~~~~~~~~~~~~~~~~~~~~~~~~
 
