diff --git a/django/test/testcases.py b/django/test/testcases.py
index 8c73c63..0a59479 100644
--- a/django/test/testcases.py
+++ b/django/test/testcases.py
@@ -273,7 +273,7 @@ class TransactionTestCase(unittest.TestCase):
             clear_url_caches()
 
     def assertRedirects(self, response, expected_url, status_code=302,
-                        target_status_code=200, host=None):
+                        target_status_code=200, host=None, msg=None):
         """Asserts that a response redirected to a specific URL, and that the
         redirect URL can be loaded.
 
@@ -283,23 +283,23 @@ class TransactionTestCase(unittest.TestCase):
         if hasattr(response, 'redirect_chain'):
             # The request was a followed redirect
             self.failUnless(len(response.redirect_chain) > 0,
-                ("Response didn't redirect as expected: Response code was %d"
+                msg or ("Response didn't redirect as expected: Response code was %d"
                 " (expected %d)" % (response.status_code, status_code)))
 
             self.assertEqual(response.redirect_chain[0][1], status_code,
-                ("Initial response didn't redirect as expected: Response code was %d"
+                msg or ("Initial response didn't redirect as expected: Response code was %d"
                  " (expected %d)" % (response.redirect_chain[0][1], status_code)))
 
             url, status_code = response.redirect_chain[-1]
 
             self.assertEqual(response.status_code, target_status_code,
-                ("Response didn't redirect as expected: Final Response code was %d"
+                msg or ("Response didn't redirect as expected: Final Response code was %d"
                 " (expected %d)" % (response.status_code, target_status_code)))
 
         else:
             # Not a followed redirect
             self.assertEqual(response.status_code, status_code,
-                ("Response didn't redirect as expected: Response code was %d"
+                msg or ("Response didn't redirect as expected: Response code was %d"
                  " (expected %d)" % (response.status_code, status_code)))
 
             url = response['Location']
@@ -310,7 +310,7 @@ class TransactionTestCase(unittest.TestCase):
             # Get the redirection page, using the same client that was used
             # to obtain the original response.
             self.assertEqual(redirect_response.status_code, target_status_code,
-                ("Couldn't retrieve redirection page '%s': response code was %d"
+                msg or ("Couldn't retrieve redirection page '%s': response code was %d"
                  " (expected %d)") %
                      (path, redirect_response.status_code, target_status_code))
 
@@ -320,10 +320,10 @@ class TransactionTestCase(unittest.TestCase):
                 e_query, e_fragment))
 
         self.assertEqual(url, expected_url,
-            "Response redirected to '%s', expected '%s'" % (url, expected_url))
+            msg or "Response redirected to '%s', expected '%s'" % (url, expected_url))
 
 
-    def assertContains(self, response, text, count=None, status_code=200):
+    def assertContains(self, response, text, count=None, status_code=200, msg=None):
         """
         Asserts that a response indicates that a page was retrieved
         successfully, (i.e., the HTTP status code was as expected), and that
@@ -332,32 +332,32 @@ class TransactionTestCase(unittest.TestCase):
         if the text occurs at least once in the response.
         """
         self.assertEqual(response.status_code, status_code,
-            "Couldn't retrieve page: Response code was %d (expected %d)'" %
+            msg or "Couldn't retrieve page: Response code was %d (expected %d)'" %
                 (response.status_code, status_code))
         text = smart_str(text, response._charset)
         real_count = response.content.count(text)
         if count is not None:
             self.assertEqual(real_count, count,
-                "Found %d instances of '%s' in response (expected %d)" %
+                msg or "Found %d instances of '%s' in response (expected %d)" %
                     (real_count, text, count))
         else:
             self.failUnless(real_count != 0,
-                            "Couldn't find '%s' in response" % text)
+                            msg or "Couldn't find '%s' in response" % text)
 
-    def assertNotContains(self, response, text, status_code=200):
+    def assertNotContains(self, response, text, status_code=200, msg=None):
         """
         Asserts that a response indicates that a page was retrieved
         successfully, (i.e., the HTTP status code was as expected), and that
         ``text`` doesn't occurs in the content of the response.
         """
         self.assertEqual(response.status_code, status_code,
-            "Couldn't retrieve page: Response code was %d (expected %d)'" %
+            msg or "Couldn't retrieve page: Response code was %d (expected %d)'" %
                 (response.status_code, status_code))
         text = smart_str(text, response._charset)
         self.assertEqual(response.content.count(text),
-             0, "Response should not contain '%s'" % text)
+             0, msg or "Response should not contain '%s'" % text)
 
-    def assertFormError(self, response, form, field, errors):
+    def assertFormError(self, response, form, field, errors, msg=None):
         """
         Asserts that a form used to render the response has a specific field
         error.
@@ -365,7 +365,7 @@ class TransactionTestCase(unittest.TestCase):
         # Put context(s) into a list to simplify processing.
         contexts = to_list(response.context)
         if not contexts:
-            self.fail('Response did not use any contexts to render the'
+            self.fail(msg or 'Response did not use any contexts to render the'
                       ' response')
 
         # Put error(s) into a list to simplify processing.
@@ -382,49 +382,49 @@ class TransactionTestCase(unittest.TestCase):
                     if field in context[form].errors:
                         field_errors = context[form].errors[field]
                         self.failUnless(err in field_errors,
-                                        "The field '%s' on form '%s' in"
+                                        msg or "The field '%s' on form '%s' in"
                                         " context %d does not contain the"
                                         " error '%s' (actual errors: %s)" %
                                             (field, form, i, err,
                                              repr(field_errors)))
                     elif field in context[form].fields:
-                        self.fail("The field '%s' on form '%s' in context %d"
+                        self.fail(msg or "The field '%s' on form '%s' in context %d"
                                   " contains no errors" % (field, form, i))
                     else:
-                        self.fail("The form '%s' in context %d does not"
+                        self.fail(msg or "The form '%s' in context %d does not"
                                   " contain the field '%s'" %
                                       (form, i, field))
                 else:
                     non_field_errors = context[form].non_field_errors()
                     self.failUnless(err in non_field_errors,
-                        "The form '%s' in context %d does not contain the"
+                        msg or "The form '%s' in context %d does not contain the"
                         " non-field error '%s' (actual errors: %s)" %
                             (form, i, err, non_field_errors))
         if not found_form:
-            self.fail("The form '%s' was not used to render the response" %
-                          form)
+            self.fail(msg or "The form '%s' was not used to render the response" %
+                      form)
 
-    def assertTemplateUsed(self, response, template_name):
+    def assertTemplateUsed(self, response, template_name, msg=None):
         """
         Asserts that the template with the provided name was used in rendering
         the response.
         """
         template_names = [t.name for t in to_list(response.template)]
         if not template_names:
-            self.fail('No templates used to render the response')
+            self.fail(msg or 'No templates used to render the response')
         self.failUnless(template_name in template_names,
-            (u"Template '%s' was not a template used to render the response."
+            msg or (u"Template '%s' was not a template used to render the response."
              u" Actual template(s) used: %s") % (template_name,
                                                  u', '.join(template_names)))
 
-    def assertTemplateNotUsed(self, response, template_name):
+    def assertTemplateNotUsed(self, response, template_name, msg=None):
         """
         Asserts that the template with the provided name was NOT used in
         rendering the response.
         """
         template_names = [t.name for t in to_list(response.template)]
         self.failIf(template_name in template_names,
-            (u"Template '%s' was used unexpectedly in rendering the"
+            msg or (u"Template '%s' was used unexpectedly in rendering the"
              u" response") % template_name)
 
 class TestCase(TransactionTestCase):
diff --git a/tests/regressiontests/test_client_regress/models.py b/tests/regressiontests/test_client_regress/models.py
index be2cb8f..f26b0e9 100644
--- a/tests/regressiontests/test_client_regress/models.py
+++ b/tests/regressiontests/test_client_regress/models.py
@@ -79,6 +79,34 @@ class AssertContainsTests(TestCase):
         self.assertNotContains(r, u'はたけ')
         self.assertNotContains(r, '\xe3\x81\xaf\xe3\x81\x9f\xe3\x81\x91'.decode('utf-8'))
 
+    def test_custom_message(self):
+        "Custom message argument is used correctly."
+        url = '/test_client_regress/no_template_view/'
+        response = self.client.get(url)
+        m = 'custom message'
+
+        try:
+            self.assertContains(response, 'never', msg=m)
+        except AssertionError, e:
+            self.assertEquals(str(e), m)
+        try:
+            self.assertContains(response, 'never', 1, msg=m)
+        except AssertionError, e:
+            self.assertEquals(str(e), m)
+        try:
+            self.assertContains(response, 'text', status_code=999, msg=m)
+        except AssertionError, e:
+            self.assertEquals(str(e), m)
+
+        try:
+             self.assertNotContains(response, 'once', msg=m)
+        except AssertionError, e:
+            self.assertEquals(str(e), m)
+        try:
+             self.assertNotContains(response, 'once', status_code=999, msg=m)
+        except AssertionError, e:
+            self.assertEquals(str(e), m)
+
 class AssertTemplateUsedTests(TestCase):
     fixtures = ['testdata.json']
 
