diff --git a/django/test/testcases.py b/django/test/testcases.py index 8c73c63..dc9aa81 100644 --- a/django/test/testcases.py +++ b/django/test/testcases.py @@ -203,6 +203,24 @@ class DocTestRunner(doctest.DocTestRunner): # side effects on other tests. transaction.rollback_unless_managed() + +import sys +from django.utils.decorators import auto_adapt_to_methods, wraps +def custom_assert_message(assert_method): + """ + Decorator for assert methods which adds a msg parameter. This parameter + will replace the message in any AssertionErrors raised. + """ + def _wrapped_method(*args, **kwargs): + msg = kwargs.pop('msg', None) + try: + return assert_method(*args, **kwargs) + except AssertionError, e: + raise e.__class__(msg or str(e)), None, sys.exc_info()[2] + return wraps(assert_method)(_wrapped_method) +custom_assert_message = auto_adapt_to_methods(custom_assert_message) + + class TransactionTestCase(unittest.TestCase): def _pre_setup(self): """Performs any pre-test setup. This includes: @@ -343,6 +361,7 @@ class TransactionTestCase(unittest.TestCase): else: self.failUnless(real_count != 0, "Couldn't find '%s' in response" % text) + assertContains = custom_assert_message(assertContains) def assertNotContains(self, response, text, status_code=200): """ @@ -356,6 +375,7 @@ class TransactionTestCase(unittest.TestCase): text = smart_str(text, response._charset) self.assertEqual(response.content.count(text), 0, "Response should not contain '%s'" % text) + assertNotContains = custom_assert_message(assertNotContains) def assertFormError(self, response, form, field, errors): """ @@ -403,6 +423,7 @@ class TransactionTestCase(unittest.TestCase): if not found_form: self.fail("The form '%s' was not used to render the response" % form) + assertFormError = custom_assert_message(assertFormError) def assertTemplateUsed(self, response, template_name): """ @@ -416,6 +437,7 @@ class TransactionTestCase(unittest.TestCase): (u"Template '%s' was not a template used to render the response." u" Actual template(s) used: %s") % (template_name, u', '.join(template_names))) + assertTemplateUsed = custom_assert_message(assertTemplateUsed) def assertTemplateNotUsed(self, response, template_name): """ @@ -426,6 +448,7 @@ class TransactionTestCase(unittest.TestCase): self.failIf(template_name in template_names, (u"Template '%s' was used unexpectedly in rendering the" u" response") % template_name) + assertTemplateNotUsed = custom_assert_message(assertTemplateNotUsed) 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']