Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

Fixed #20004 -- Moved non DB-related assertions to SimpleTestCase.

Thanks zalew for the suggestion and work on a patch.

Also updated, tweaked and fixed testing documentation.
  • Loading branch information...
commit 0a50311063c416ec4d39f518e8d8110dd7eddbdf 1 parent 69523c1
Ramiro Morales authored May 18, 2013
515  django/test/testcases.py
@@ -231,6 +231,10 @@ def message(self):
231 231
 
232 232
 class SimpleTestCase(ut2.TestCase):
233 233
 
  234
+    # The class we'll use for the test client self.client.
  235
+    # Can be overridden in derived classes.
  236
+    client_class = Client
  237
+
234 238
     _warn_txt = ("save_warnings_state/restore_warnings_state "
235 239
         "django.test.*TestCase methods are deprecated. Use Python's "
236 240
         "warnings.catch_warnings context manager instead.")
@@ -264,10 +268,31 @@ def __call__(self, result=None):
264 268
                 return
265 269
 
266 270
     def _pre_setup(self):
267  
-        pass
  271
+        """Performs any pre-test setup. This includes:
  272
+
  273
+           * If the Test Case class has a 'urls' member, replace the
  274
+             ROOT_URLCONF with it.
  275
+           * Clearing the mail test outbox.
  276
+        """
  277
+        self.client = self.client_class()
  278
+        self._urlconf_setup()
  279
+        mail.outbox = []
  280
+
  281
+    def _urlconf_setup(self):
  282
+        set_urlconf(None)
  283
+        if hasattr(self, 'urls'):
  284
+            self._old_root_urlconf = settings.ROOT_URLCONF
  285
+            settings.ROOT_URLCONF = self.urls
  286
+            clear_url_caches()
268 287
 
269 288
     def _post_teardown(self):
270  
-        pass
  289
+        self._urlconf_teardown()
  290
+
  291
+    def _urlconf_teardown(self):
  292
+        set_urlconf(None)
  293
+        if hasattr(self, '_old_root_urlconf'):
  294
+            settings.ROOT_URLCONF = self._old_root_urlconf
  295
+            clear_url_caches()
271 296
 
272 297
     def save_warnings_state(self):
273 298
         """
@@ -291,258 +316,6 @@ def settings(self, **kwargs):
291 316
         """
292 317
         return override_settings(**kwargs)
293 318
 
294  
-    def assertRaisesMessage(self, expected_exception, expected_message,
295  
-                           callable_obj=None, *args, **kwargs):
296  
-        """
297  
-        Asserts that the message in a raised exception matches the passed
298  
-        value.
299  
-
300  
-        Args:
301  
-            expected_exception: Exception class expected to be raised.
302  
-            expected_message: expected error message string value.
303  
-            callable_obj: Function to be called.
304  
-            args: Extra args.
305  
-            kwargs: Extra kwargs.
306  
-        """
307  
-        return six.assertRaisesRegex(self, expected_exception,
308  
-                re.escape(expected_message), callable_obj, *args, **kwargs)
309  
-
310  
-    def assertFieldOutput(self, fieldclass, valid, invalid, field_args=None,
311  
-            field_kwargs=None, empty_value=''):
312  
-        """
313  
-        Asserts that a form field behaves correctly with various inputs.
314  
-
315  
-        Args:
316  
-            fieldclass: the class of the field to be tested.
317  
-            valid: a dictionary mapping valid inputs to their expected
318  
-                    cleaned values.
319  
-            invalid: a dictionary mapping invalid inputs to one or more
320  
-                    raised error messages.
321  
-            field_args: the args passed to instantiate the field
322  
-            field_kwargs: the kwargs passed to instantiate the field
323  
-            empty_value: the expected clean output for inputs in empty_values
324  
-
325  
-        """
326  
-        if field_args is None:
327  
-            field_args = []
328  
-        if field_kwargs is None:
329  
-            field_kwargs = {}
330  
-        required = fieldclass(*field_args, **field_kwargs)
331  
-        optional = fieldclass(*field_args,
332  
-                              **dict(field_kwargs, required=False))
333  
-        # test valid inputs
334  
-        for input, output in valid.items():
335  
-            self.assertEqual(required.clean(input), output)
336  
-            self.assertEqual(optional.clean(input), output)
337  
-        # test invalid inputs
338  
-        for input, errors in invalid.items():
339  
-            with self.assertRaises(ValidationError) as context_manager:
340  
-                required.clean(input)
341  
-            self.assertEqual(context_manager.exception.messages, errors)
342  
-
343  
-            with self.assertRaises(ValidationError) as context_manager:
344  
-                optional.clean(input)
345  
-            self.assertEqual(context_manager.exception.messages, errors)
346  
-        # test required inputs
347  
-        error_required = [force_text(required.error_messages['required'])]
348  
-        for e in required.empty_values:
349  
-            with self.assertRaises(ValidationError) as context_manager:
350  
-                required.clean(e)
351  
-            self.assertEqual(context_manager.exception.messages,
352  
-                             error_required)
353  
-            self.assertEqual(optional.clean(e), empty_value)
354  
-        # test that max_length and min_length are always accepted
355  
-        if issubclass(fieldclass, CharField):
356  
-            field_kwargs.update({'min_length':2, 'max_length':20})
357  
-            self.assertTrue(isinstance(fieldclass(*field_args, **field_kwargs),
358  
-                                       fieldclass))
359  
-
360  
-    def assertHTMLEqual(self, html1, html2, msg=None):
361  
-        """
362  
-        Asserts that two HTML snippets are semantically the same.
363  
-        Whitespace in most cases is ignored, and attribute ordering is not
364  
-        significant. The passed-in arguments must be valid HTML.
365  
-        """
366  
-        dom1 = assert_and_parse_html(self, html1, msg,
367  
-            'First argument is not valid HTML:')
368  
-        dom2 = assert_and_parse_html(self, html2, msg,
369  
-            'Second argument is not valid HTML:')
370  
-
371  
-        if dom1 != dom2:
372  
-            standardMsg = '%s != %s' % (
373  
-                safe_repr(dom1, True), safe_repr(dom2, True))
374  
-            diff = ('\n' + '\n'.join(difflib.ndiff(
375  
-                           six.text_type(dom1).splitlines(),
376  
-                           six.text_type(dom2).splitlines())))
377  
-            standardMsg = self._truncateMessage(standardMsg, diff)
378  
-            self.fail(self._formatMessage(msg, standardMsg))
379  
-
380  
-    def assertHTMLNotEqual(self, html1, html2, msg=None):
381  
-        """Asserts that two HTML snippets are not semantically equivalent."""
382  
-        dom1 = assert_and_parse_html(self, html1, msg,
383  
-            'First argument is not valid HTML:')
384  
-        dom2 = assert_and_parse_html(self, html2, msg,
385  
-            'Second argument is not valid HTML:')
386  
-
387  
-        if dom1 == dom2:
388  
-            standardMsg = '%s == %s' % (
389  
-                safe_repr(dom1, True), safe_repr(dom2, True))
390  
-            self.fail(self._formatMessage(msg, standardMsg))
391  
-
392  
-    def assertInHTML(self, needle, haystack, count = None, msg_prefix=''):
393  
-        needle = assert_and_parse_html(self, needle, None,
394  
-            'First argument is not valid HTML:')
395  
-        haystack = assert_and_parse_html(self, haystack, None,
396  
-            'Second argument is not valid HTML:')
397  
-        real_count = haystack.count(needle)
398  
-        if count is not None:
399  
-            self.assertEqual(real_count, count,
400  
-                msg_prefix + "Found %d instances of '%s' in response"
401  
-                " (expected %d)" % (real_count, needle, count))
402  
-        else:
403  
-            self.assertTrue(real_count != 0,
404  
-                msg_prefix + "Couldn't find '%s' in response" % needle)
405  
-
406  
-    def assertJSONEqual(self, raw, expected_data, msg=None):
407  
-        try:
408  
-            data = json.loads(raw)
409  
-        except ValueError:
410  
-            self.fail("First argument is not valid JSON: %r" % raw)
411  
-        if isinstance(expected_data, six.string_types):
412  
-            try:
413  
-                expected_data = json.loads(expected_data)
414  
-            except ValueError:
415  
-                self.fail("Second argument is not valid JSON: %r" % expected_data)
416  
-        self.assertEqual(data, expected_data, msg=msg)
417  
-
418  
-    def assertXMLEqual(self, xml1, xml2, msg=None):
419  
-        """
420  
-        Asserts that two XML snippets are semantically the same.
421  
-        Whitespace in most cases is ignored, and attribute ordering is not
422  
-        significant. The passed-in arguments must be valid XML.
423  
-        """
424  
-        try:
425  
-            result = compare_xml(xml1, xml2)
426  
-        except Exception as e:
427  
-            standardMsg = 'First or second argument is not valid XML\n%s' % e
428  
-            self.fail(self._formatMessage(msg, standardMsg))
429  
-        else:
430  
-            if not result:
431  
-                standardMsg = '%s != %s' % (safe_repr(xml1, True), safe_repr(xml2, True))
432  
-                self.fail(self._formatMessage(msg, standardMsg))
433  
-
434  
-    def assertXMLNotEqual(self, xml1, xml2, msg=None):
435  
-        """
436  
-        Asserts that two XML snippets are not semantically equivalent.
437  
-        Whitespace in most cases is ignored, and attribute ordering is not
438  
-        significant. The passed-in arguments must be valid XML.
439  
-        """
440  
-        try:
441  
-            result = compare_xml(xml1, xml2)
442  
-        except Exception as e:
443  
-            standardMsg = 'First or second argument is not valid XML\n%s' % e
444  
-            self.fail(self._formatMessage(msg, standardMsg))
445  
-        else:
446  
-            if result:
447  
-                standardMsg = '%s == %s' % (safe_repr(xml1, True), safe_repr(xml2, True))
448  
-                self.fail(self._formatMessage(msg, standardMsg))
449  
-
450  
-
451  
-class TransactionTestCase(SimpleTestCase):
452  
-
453  
-    # The class we'll use for the test client self.client.
454  
-    # Can be overridden in derived classes.
455  
-    client_class = Client
456  
-
457  
-    # Subclasses can ask for resetting of auto increment sequence before each
458  
-    # test case
459  
-    reset_sequences = False
460  
-
461  
-    def _pre_setup(self):
462  
-        """Performs any pre-test setup. This includes:
463  
-
464  
-            * Flushing the database.
465  
-            * If the Test Case class has a 'fixtures' member, installing the
466  
-              named fixtures.
467  
-            * If the Test Case class has a 'urls' member, replace the
468  
-              ROOT_URLCONF with it.
469  
-            * Clearing the mail test outbox.
470  
-        """
471  
-        self.client = self.client_class()
472  
-        self._fixture_setup()
473  
-        self._urlconf_setup()
474  
-        mail.outbox = []
475  
-
476  
-    def _databases_names(self, include_mirrors=True):
477  
-        # If the test case has a multi_db=True flag, act on all databases,
478  
-        # including mirrors or not. Otherwise, just on the default DB.
479  
-        if getattr(self, 'multi_db', False):
480  
-            return [alias for alias in connections
481  
-                    if include_mirrors or not connections[alias].settings_dict['TEST_MIRROR']]
482  
-        else:
483  
-            return [DEFAULT_DB_ALIAS]
484  
-
485  
-    def _reset_sequences(self, db_name):
486  
-        conn = connections[db_name]
487  
-        if conn.features.supports_sequence_reset:
488  
-            sql_list = \
489  
-                conn.ops.sequence_reset_by_name_sql(no_style(),
490  
-                                                    conn.introspection.sequence_list())
491  
-            if sql_list:
492  
-                with transaction.commit_on_success_unless_managed(using=db_name):
493  
-                    cursor = conn.cursor()
494  
-                    for sql in sql_list:
495  
-                        cursor.execute(sql)
496  
-
497  
-    def _fixture_setup(self):
498  
-        for db_name in self._databases_names(include_mirrors=False):
499  
-            # Reset sequences
500  
-            if self.reset_sequences:
501  
-                self._reset_sequences(db_name)
502  
-
503  
-            if hasattr(self, 'fixtures'):
504  
-                # We have to use this slightly awkward syntax due to the fact
505  
-                # that we're using *args and **kwargs together.
506  
-                call_command('loaddata', *self.fixtures,
507  
-                             **{'verbosity': 0, 'database': db_name, 'skip_validation': True})
508  
-
509  
-    def _urlconf_setup(self):
510  
-        set_urlconf(None)
511  
-        if hasattr(self, 'urls'):
512  
-            self._old_root_urlconf = settings.ROOT_URLCONF
513  
-            settings.ROOT_URLCONF = self.urls
514  
-            clear_url_caches()
515  
-
516  
-    def _post_teardown(self):
517  
-        """ Performs any post-test things. This includes:
518  
-
519  
-            * Putting back the original ROOT_URLCONF if it was changed.
520  
-            * Force closing the connection, so that the next test gets
521  
-              a clean cursor.
522  
-        """
523  
-        self._fixture_teardown()
524  
-        self._urlconf_teardown()
525  
-        # Some DB cursors include SQL statements as part of cursor
526  
-        # creation. If you have a test that does rollback, the effect
527  
-        # of these statements is lost, which can effect the operation
528  
-        # of tests (e.g., losing a timezone setting causing objects to
529  
-        # be created with the wrong time).
530  
-        # To make sure this doesn't happen, get a clean connection at the
531  
-        # start of every test.
532  
-        for conn in connections.all():
533  
-            conn.close()
534  
-
535  
-    def _fixture_teardown(self):
536  
-        for db in self._databases_names(include_mirrors=False):
537  
-            call_command('flush', verbosity=0, interactive=False, database=db,
538  
-                         skip_validation=True, reset_sequences=False)
539  
-
540  
-    def _urlconf_teardown(self):
541  
-        set_urlconf(None)
542  
-        if hasattr(self, '_old_root_urlconf'):
543  
-            settings.ROOT_URLCONF = self._old_root_urlconf
544  
-            clear_url_caches()
545  
-
546 319
     def assertRedirects(self, response, expected_url, status_code=302,
547 320
                         target_status_code=200, host=None, msg_prefix=''):
548 321
         """Asserts that a response redirected to a specific URL, and that the
@@ -787,6 +560,236 @@ def assertTemplateNotUsed(self, response=None, template_name=None, msg_prefix=''
787 560
             msg_prefix + "Template '%s' was used unexpectedly in rendering"
788 561
             " the response" % template_name)
789 562
 
  563
+    def assertRaisesMessage(self, expected_exception, expected_message,
  564
+                           callable_obj=None, *args, **kwargs):
  565
+        """
  566
+        Asserts that the message in a raised exception matches the passed
  567
+        value.
  568
+
  569
+        Args:
  570
+            expected_exception: Exception class expected to be raised.
  571
+            expected_message: expected error message string value.
  572
+            callable_obj: Function to be called.
  573
+            args: Extra args.
  574
+            kwargs: Extra kwargs.
  575
+        """
  576
+        return six.assertRaisesRegex(self, expected_exception,
  577
+                re.escape(expected_message), callable_obj, *args, **kwargs)
  578
+
  579
+    def assertFieldOutput(self, fieldclass, valid, invalid, field_args=None,
  580
+            field_kwargs=None, empty_value=''):
  581
+        """
  582
+        Asserts that a form field behaves correctly with various inputs.
  583
+
  584
+        Args:
  585
+            fieldclass: the class of the field to be tested.
  586
+            valid: a dictionary mapping valid inputs to their expected
  587
+                    cleaned values.
  588
+            invalid: a dictionary mapping invalid inputs to one or more
  589
+                    raised error messages.
  590
+            field_args: the args passed to instantiate the field
  591
+            field_kwargs: the kwargs passed to instantiate the field
  592
+            empty_value: the expected clean output for inputs in empty_values
  593
+
  594
+        """
  595
+        if field_args is None:
  596
+            field_args = []
  597
+        if field_kwargs is None:
  598
+            field_kwargs = {}
  599
+        required = fieldclass(*field_args, **field_kwargs)
  600
+        optional = fieldclass(*field_args,
  601
+                              **dict(field_kwargs, required=False))
  602
+        # test valid inputs
  603
+        for input, output in valid.items():
  604
+            self.assertEqual(required.clean(input), output)
  605
+            self.assertEqual(optional.clean(input), output)
  606
+        # test invalid inputs
  607
+        for input, errors in invalid.items():
  608
+            with self.assertRaises(ValidationError) as context_manager:
  609
+                required.clean(input)
  610
+            self.assertEqual(context_manager.exception.messages, errors)
  611
+
  612
+            with self.assertRaises(ValidationError) as context_manager:
  613
+                optional.clean(input)
  614
+            self.assertEqual(context_manager.exception.messages, errors)
  615
+        # test required inputs
  616
+        error_required = [force_text(required.error_messages['required'])]
  617
+        for e in required.empty_values:
  618
+            with self.assertRaises(ValidationError) as context_manager:
  619
+                required.clean(e)
  620
+            self.assertEqual(context_manager.exception.messages,
  621
+                             error_required)
  622
+            self.assertEqual(optional.clean(e), empty_value)
  623
+        # test that max_length and min_length are always accepted
  624
+        if issubclass(fieldclass, CharField):
  625
+            field_kwargs.update({'min_length':2, 'max_length':20})
  626
+            self.assertTrue(isinstance(fieldclass(*field_args, **field_kwargs),
  627
+                                       fieldclass))
  628
+
  629
+    def assertHTMLEqual(self, html1, html2, msg=None):
  630
+        """
  631
+        Asserts that two HTML snippets are semantically the same.
  632
+        Whitespace in most cases is ignored, and attribute ordering is not
  633
+        significant. The passed-in arguments must be valid HTML.
  634
+        """
  635
+        dom1 = assert_and_parse_html(self, html1, msg,
  636
+            'First argument is not valid HTML:')
  637
+        dom2 = assert_and_parse_html(self, html2, msg,
  638
+            'Second argument is not valid HTML:')
  639
+
  640
+        if dom1 != dom2:
  641
+            standardMsg = '%s != %s' % (
  642
+                safe_repr(dom1, True), safe_repr(dom2, True))
  643
+            diff = ('\n' + '\n'.join(difflib.ndiff(
  644
+                           six.text_type(dom1).splitlines(),
  645
+                           six.text_type(dom2).splitlines())))
  646
+            standardMsg = self._truncateMessage(standardMsg, diff)
  647
+            self.fail(self._formatMessage(msg, standardMsg))
  648
+
  649
+    def assertHTMLNotEqual(self, html1, html2, msg=None):
  650
+        """Asserts that two HTML snippets are not semantically equivalent."""
  651
+        dom1 = assert_and_parse_html(self, html1, msg,
  652
+            'First argument is not valid HTML:')
  653
+        dom2 = assert_and_parse_html(self, html2, msg,
  654
+            'Second argument is not valid HTML:')
  655
+
  656
+        if dom1 == dom2:
  657
+            standardMsg = '%s == %s' % (
  658
+                safe_repr(dom1, True), safe_repr(dom2, True))
  659
+            self.fail(self._formatMessage(msg, standardMsg))
  660
+
  661
+    def assertInHTML(self, needle, haystack, count=None, msg_prefix=''):
  662
+        needle = assert_and_parse_html(self, needle, None,
  663
+            'First argument is not valid HTML:')
  664
+        haystack = assert_and_parse_html(self, haystack, None,
  665
+            'Second argument is not valid HTML:')
  666
+        real_count = haystack.count(needle)
  667
+        if count is not None:
  668
+            self.assertEqual(real_count, count,
  669
+                msg_prefix + "Found %d instances of '%s' in response"
  670
+                " (expected %d)" % (real_count, needle, count))
  671
+        else:
  672
+            self.assertTrue(real_count != 0,
  673
+                msg_prefix + "Couldn't find '%s' in response" % needle)
  674
+
  675
+    def assertJSONEqual(self, raw, expected_data, msg=None):
  676
+        try:
  677
+            data = json.loads(raw)
  678
+        except ValueError:
  679
+            self.fail("First argument is not valid JSON: %r" % raw)
  680
+        if isinstance(expected_data, six.string_types):
  681
+            try:
  682
+                expected_data = json.loads(expected_data)
  683
+            except ValueError:
  684
+                self.fail("Second argument is not valid JSON: %r" % expected_data)
  685
+        self.assertEqual(data, expected_data, msg=msg)
  686
+
  687
+    def assertXMLEqual(self, xml1, xml2, msg=None):
  688
+        """
  689
+        Asserts that two XML snippets are semantically the same.
  690
+        Whitespace in most cases is ignored, and attribute ordering is not
  691
+        significant. The passed-in arguments must be valid XML.
  692
+        """
  693
+        try:
  694
+            result = compare_xml(xml1, xml2)
  695
+        except Exception as e:
  696
+            standardMsg = 'First or second argument is not valid XML\n%s' % e
  697
+            self.fail(self._formatMessage(msg, standardMsg))
  698
+        else:
  699
+            if not result:
  700
+                standardMsg = '%s != %s' % (safe_repr(xml1, True), safe_repr(xml2, True))
  701
+                self.fail(self._formatMessage(msg, standardMsg))
  702
+
  703
+    def assertXMLNotEqual(self, xml1, xml2, msg=None):
  704
+        """
  705
+        Asserts that two XML snippets are not semantically equivalent.
  706
+        Whitespace in most cases is ignored, and attribute ordering is not
  707
+        significant. The passed-in arguments must be valid XML.
  708
+        """
  709
+        try:
  710
+            result = compare_xml(xml1, xml2)
  711
+        except Exception as e:
  712
+            standardMsg = 'First or second argument is not valid XML\n%s' % e
  713
+            self.fail(self._formatMessage(msg, standardMsg))
  714
+        else:
  715
+            if result:
  716
+                standardMsg = '%s == %s' % (safe_repr(xml1, True), safe_repr(xml2, True))
  717
+                self.fail(self._formatMessage(msg, standardMsg))
  718
+
  719
+
  720
+class TransactionTestCase(SimpleTestCase):
  721
+
  722
+    # Subclasses can ask for resetting of auto increment sequence before each
  723
+    # test case
  724
+    reset_sequences = False
  725
+
  726
+    def _pre_setup(self):
  727
+        """Performs any pre-test setup. This includes:
  728
+
  729
+           * Flushing the database.
  730
+           * If the Test Case class has a 'fixtures' member, installing the
  731
+             named fixtures.
  732
+        """
  733
+        super(TransactionTestCase, self)._pre_setup()
  734
+        self._fixture_setup()
  735
+
  736
+    def _databases_names(self, include_mirrors=True):
  737
+        # If the test case has a multi_db=True flag, act on all databases,
  738
+        # including mirrors or not. Otherwise, just on the default DB.
  739
+        if getattr(self, 'multi_db', False):
  740
+            return [alias for alias in connections
  741
+                    if include_mirrors or not connections[alias].settings_dict['TEST_MIRROR']]
  742
+        else:
  743
+            return [DEFAULT_DB_ALIAS]
  744
+
  745
+    def _reset_sequences(self, db_name):
  746
+        conn = connections[db_name]
  747
+        if conn.features.supports_sequence_reset:
  748
+            sql_list = \
  749
+                conn.ops.sequence_reset_by_name_sql(no_style(),
  750
+                                                    conn.introspection.sequence_list())
  751
+            if sql_list:
  752
+                with transaction.commit_on_success_unless_managed(using=db_name):
  753
+                    cursor = conn.cursor()
  754
+                    for sql in sql_list:
  755
+                        cursor.execute(sql)
  756
+
  757
+    def _fixture_setup(self):
  758
+        for db_name in self._databases_names(include_mirrors=False):
  759
+            # Reset sequences
  760
+            if self.reset_sequences:
  761
+                self._reset_sequences(db_name)
  762
+
  763
+            if hasattr(self, 'fixtures'):
  764
+                # We have to use this slightly awkward syntax due to the fact
  765
+                # that we're using *args and **kwargs together.
  766
+                call_command('loaddata', *self.fixtures,
  767
+                             **{'verbosity': 0, 'database': db_name, 'skip_validation': True})
  768
+
  769
+    def _post_teardown(self):
  770
+        """Performs any post-test things. This includes:
  771
+
  772
+           * Putting back the original ROOT_URLCONF if it was changed.
  773
+           * Force closing the connection, so that the next test gets
  774
+             a clean cursor.
  775
+        """
  776
+        self._fixture_teardown()
  777
+        super(TransactionTestCase, self)._post_teardown()
  778
+        # Some DB cursors include SQL statements as part of cursor
  779
+        # creation. If you have a test that does rollback, the effect
  780
+        # of these statements is lost, which can effect the operation
  781
+        # of tests (e.g., losing a timezone setting causing objects to
  782
+        # be created with the wrong time).
  783
+        # To make sure this doesn't happen, get a clean connection at the
  784
+        # start of every test.
  785
+        for conn in connections.all():
  786
+            conn.close()
  787
+
  788
+    def _fixture_teardown(self):
  789
+        for db_name in self._databases_names(include_mirrors=False):
  790
+            call_command('flush', verbosity=0, interactive=False, database=db_name,
  791
+                         skip_validation=True, reset_sequences=False)
  792
+
790 793
     def assertQuerysetEqual(self, qs, values, transform=repr, ordered=True):
791 794
         items = six.moves.map(transform, qs)
792 795
         if not ordered:
@@ -841,14 +844,14 @@ def _fixture_setup(self):
841 844
         # Remove this when the legacy transaction management goes away.
842 845
         disable_transaction_methods()
843 846
 
844  
-        for db in self._databases_names(include_mirrors=False):
  847
+        for db_name in self._databases_names(include_mirrors=False):
845 848
             if hasattr(self, 'fixtures'):
846 849
                 try:
847 850
                     call_command('loaddata', *self.fixtures,
848 851
                                  **{
849 852
                                     'verbosity': 0,
850 853
                                     'commit': False,
851  
-                                    'database': db,
  854
+                                    'database': db_name,
852 855
                                     'skip_validation': True,
853 856
                                  })
854 857
                 except Exception:
4  docs/intro/tutorial05.txt
@@ -503,8 +503,8 @@ of the process of creating polls.
503 503
 message: "No polls are available." and verifies the ``latest_poll_list`` is
504 504
 empty. Note that the :class:`django.test.TestCase` class provides some
505 505
 additional assertion methods. In these examples, we use
506  
-:meth:`~django.test.TestCase.assertContains()` and
507  
-:meth:`~django.test.TestCase.assertQuerysetEqual()`.
  506
+:meth:`~django.test.SimpleTestCase.assertContains()` and
  507
+:meth:`~django.test.TransactionTestCase.assertQuerysetEqual()`.
508 508
 
509 509
 In ``test_index_view_with_a_past_poll``, we create a poll and verify that it
510 510
 appears in the list.
2  docs/ref/contrib/contenttypes.txt
@@ -329,7 +329,7 @@ model:
329 329
 .. admonition:: Serializing references to ``ContentType`` objects
330 330
 
331 331
    If you're serializing data (for example, when generating
332  
-   :class:`~django.test.TestCase.fixtures`) from a model that implements
  332
+   :class:`~django.test.TransactionTestCase.fixtures`) from a model that implements
333 333
    generic relations, you should probably be using a natural key to uniquely
334 334
    identify related :class:`~django.contrib.contenttypes.models.ContentType`
335 335
    objects. See :ref:`natural keys<topics-serialization-natural-keys>` and
2  docs/releases/1.3-alpha-1.txt
@@ -154,7 +154,7 @@ requests. These include:
154 154
   requests in tests.
155 155
 
156 156
 * A new test assertion --
157  
-  :meth:`~django.test.TestCase.assertNumQueries` -- making it
  157
+  :meth:`~django.test.TransactionTestCase.assertNumQueries` -- making it
158 158
   easier to test the database activity associated with a view.
159 159
 
160 160
 
2  docs/releases/1.3.txt
@@ -299,7 +299,7 @@ requests. These include:
299 299
   in tests.
300 300
 
301 301
 * A new test assertion --
302  
-  :meth:`~django.test.TestCase.assertNumQueries` -- making it
  302
+  :meth:`~django.test.TransactionTestCase.assertNumQueries` -- making it
303 303
   easier to test the database activity associated with a view.
304 304
 
305 305
 * Support for lookups spanning relations in admin's
8  docs/releases/1.4.txt
@@ -541,8 +541,8 @@ compare HTML directly with the new
541 541
 :meth:`~django.test.SimpleTestCase.assertHTMLEqual` and
542 542
 :meth:`~django.test.SimpleTestCase.assertHTMLNotEqual` assertions, or use
543 543
 the ``html=True`` flag with
544  
-:meth:`~django.test.TestCase.assertContains` and
545  
-:meth:`~django.test.TestCase.assertNotContains` to test whether the
  544
+:meth:`~django.test.SimpleTestCase.assertContains` and
  545
+:meth:`~django.test.SimpleTestCase.assertNotContains` to test whether the
546 546
 client's response contains a given HTML fragment. See the :ref:`assertions
547 547
 documentation <assertions>` for more.
548 548
 
@@ -1093,8 +1093,8 @@ wild, because they would confuse browsers too.
1093 1093
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1094 1094
 
1095 1095
 It's now possible to check whether a template was used within a block of
1096  
-code with :meth:`~django.test.TestCase.assertTemplateUsed` and
1097  
-:meth:`~django.test.TestCase.assertTemplateNotUsed`. And they
  1096
+code with :meth:`~django.test.SimpleTestCase.assertTemplateUsed` and
  1097
+:meth:`~django.test.SimpleTestCase.assertTemplateNotUsed`. And they
1098 1098
 can be used as a context manager::
1099 1099
 
1100 1100
     with self.assertTemplateUsed('index.html'):
7  docs/releases/1.6.txt
@@ -271,9 +271,10 @@ The changes in transaction management may result in additional statements to
271 271
 create, release or rollback savepoints. This is more likely to happen with
272 272
 SQLite, since it didn't support savepoints until this release.
273 273
 
274  
-If tests using :meth:`~django.test.TestCase.assertNumQueries` fail because of
275  
-a higher number of queries than expected, check that the extra queries are
276  
-related to savepoints, and adjust the expected number of queries accordingly.
  274
+If tests using :meth:`~django.test.TransactionTestCase.assertNumQueries` fail
  275
+because of a higher number of queries than expected, check that the extra
  276
+queries are related to savepoints, and adjust the expected number of queries
  277
+accordingly.
277 278
 
278 279
 Autocommit option for PostgreSQL
279 280
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
4  docs/topics/python3.txt
@@ -201,8 +201,8 @@ According to :pep:`3333`:
201 201
 Specifically, :attr:`HttpResponse.content <django.http.HttpResponse.content>`
202 202
 contains ``bytes``, which may become an issue if you compare it with a
203 203
 ``str`` in your tests. The preferred solution is to rely on
204  
-:meth:`~django.test.TestCase.assertContains` and
205  
-:meth:`~django.test.TestCase.assertNotContains`. These methods accept a
  204
+:meth:`~django.test.SimpleTestCase.assertContains` and
  205
+:meth:`~django.test.SimpleTestCase.assertNotContains`. These methods accept a
206 206
 response and a unicode string as arguments.
207 207
 
208 208
 Coding guidelines
235  docs/topics/testing/overview.txt
@@ -21,17 +21,16 @@ module defines tests using a class-based approach.
21 21
 
22 22
 .. admonition:: unittest2
23 23
 
24  
-    Python 2.7 introduced some major changes to the unittest library,
  24
+    Python 2.7 introduced some major changes to the ``unittest`` library,
25 25
     adding some extremely useful features. To ensure that every Django
26 26
     project can benefit from these new features, Django ships with a
27  
-    copy of unittest2_, a copy of the Python 2.7 unittest library,
28  
-    backported for Python 2.6 compatibility.
  27
+    copy of unittest2_, a copy of Python 2.7's ``unittest``, backported for
  28
+    Python 2.6 compatibility.
29 29
 
30 30
     To access this library, Django provides the
31 31
     ``django.utils.unittest`` module alias. If you are using Python
32  
-    2.7, or you have installed unittest2 locally, Django will map the
33  
-    alias to the installed version of the unittest library. Otherwise,
34  
-    Django will use its own bundled version of unittest2.
  32
+    2.7, or you have installed ``unittest2`` locally, Django will map the alias
  33
+    to it. Otherwise, Django will use its own bundled version of ``unittest2``.
35 34
 
36 35
     To use this alias, simply use::
37 36
 
@@ -41,8 +40,8 @@ module defines tests using a class-based approach.
41 40
 
42 41
         import unittest
43 42
 
44  
-    If you want to continue to use the base unittest library, you can --
45  
-    you just won't get any of the nice new unittest2 features.
  43
+    If you want to continue to use the legacy ``unittest`` library, you can --
  44
+    you just won't get any of the nice new ``unittest2`` features.
46 45
 
47 46
 .. _unittest2: http://pypi.python.org/pypi/unittest2
48 47
 
@@ -858,24 +857,46 @@ SimpleTestCase
858 857
 
859 858
 .. class:: SimpleTestCase()
860 859
 
861  
-A very thin subclass of :class:`unittest.TestCase`, it extends it with some
862  
-basic functionality like:
  860
+A thin subclass of :class:`unittest.TestCase`, it extends it with some basic
  861
+functionality like:
863 862
 
864 863
 * Saving and restoring the Python warning machinery state.
865  
-* Checking that a callable :meth:`raises a certain exception <SimpleTestCase.assertRaisesMessage>`.
866  
-* :meth:`Testing form field rendering <SimpleTestCase.assertFieldOutput>`.
867  
-* Testing server :ref:`HTML responses for the presence/lack of a given fragment <assertions>`.
868  
-* The ability to run tests with :ref:`modified settings <overriding-settings>`
  864
+* Some useful assertions like:
  865
+
  866
+  * Checking that a callable :meth:`raises a certain exception
  867
+    <SimpleTestCase.assertRaisesMessage>`.
  868
+  * Testing form field :meth:`rendering and error treatment
  869
+    <SimpleTestCase.assertFieldOutput>`.
  870
+  * Testing :meth:`HTML responses for the presence/lack of a given fragment
  871
+    <SimpleTestCase.assertContains>`.
  872
+  * Verifying that a template :meth:`has/hasn't been used to generate a given
  873
+    response content <SimpleTestCase.assertTemplateUsed>`.
  874
+  * Verifying a HTTP :meth:`redirect <SimpleTestCase.assertRedirects>` is
  875
+    performed by the app.
  876
+  * Robustly testing two :meth:`HTML fragments <SimpleTestCase.assertHTMLEqual>`
  877
+    for equality/inequality or :meth:`containment <SimpleTestCase.assertInHTML>`.
  878
+  * Robustly testing two :meth:`XML fragments <SimpleTestCase.assertXMLEqual>`
  879
+    for equality/inequality.
  880
+  * Robustly testing two :meth:`JSON fragments <SimpleTestCase.assertJSONEqual>`
  881
+    for equality.
  882
+
  883
+* The ability to run tests with :ref:`modified settings <overriding-settings>`.
  884
+* Using the :attr:`~SimpleTestCase.client` :class:`~django.test.client.Client`.
  885
+* Custom test-time :attr:`URL maps <SimpleTestCase.urls>`.
  886
+
  887
+.. versionchanged:: 1.6
  888
+
  889
+    The latter two features were moved from ``TransactionTestCase`` to
  890
+    ``SimpleTestCase`` in Django 1.6.
869 891
 
870 892
 If you need any of the other more complex and heavyweight Django-specific
871 893
 features like:
872 894
 
873  
-* Using the :attr:`~TestCase.client` :class:`~django.test.client.Client`.
874 895
 * Testing or using the ORM.
875  
-* Database :attr:`~TestCase.fixtures`.
876  
-* Custom test-time :attr:`URL maps <TestCase.urls>`.
  896
+* Database :attr:`~TransactionTestCase.fixtures`.
877 897
 * Test :ref:`skipping based on database backend features <skipping-tests>`.
878  
-* The remaining specialized :ref:`assert* <assertions>` methods.
  898
+* The remaining specialized :meth:`assert*
  899
+  <TransactionTestCase.assertQuerysetEqual>` methods.
879 900
 
880 901
 then you should use :class:`~django.test.TransactionTestCase` or
881 902
 :class:`~django.test.TestCase` instead.
@@ -1137,9 +1158,9 @@ Test cases features
1137 1158
 Default test client
1138 1159
 ~~~~~~~~~~~~~~~~~~~
1139 1160
 
1140  
-.. attribute:: TestCase.client
  1161
+.. attribute:: SimpleTestCase.client
1141 1162
 
1142  
-Every test case in a ``django.test.TestCase`` instance has access to an
  1163
+Every test case in a ``django.test.*TestCase`` instance has access to an
1143 1164
 instance of a Django test client. This client can be accessed as
1144 1165
 ``self.client``. This client is recreated for each test, so you don't have to
1145 1166
 worry about state (such as cookies) carrying over from one test to another.
@@ -1176,10 +1197,10 @@ This means, instead of instantiating a ``Client`` in each test::
1176 1197
 Customizing the test client
1177 1198
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~
1178 1199
 
1179  
-.. attribute:: TestCase.client_class
  1200
+.. attribute:: SimpleTestCase.client_class
1180 1201
 
1181 1202
 If you want to use a different ``Client`` class (for example, a subclass
1182  
-with customized behavior), use the :attr:`~TestCase.client_class` class
  1203
+with customized behavior), use the :attr:`~SimpleTestCase.client_class` class
1183 1204
 attribute::
1184 1205
 
1185 1206
     from django.test import TestCase
@@ -1200,11 +1221,12 @@ attribute::
1200 1221
 Fixture loading
1201 1222
 ~~~~~~~~~~~~~~~
1202 1223
 
1203  
-.. attribute:: TestCase.fixtures
  1224
+.. attribute:: TransactionTestCase.fixtures
1204 1225
 
1205 1226
 A test case for a database-backed Web site isn't much use if there isn't any
1206 1227
 data in the database. To make it easy to put test data into the database,
1207  
-Django's custom ``TestCase`` class provides a way of loading **fixtures**.
  1228
+Django's custom ``TransactionTestCase`` class provides a way of loading
  1229
+**fixtures**.
1208 1230
 
1209 1231
 A fixture is a collection of data that Django knows how to import into a
1210 1232
 database. For example, if your site has user accounts, you might set up a
@@ -1273,7 +1295,7 @@ or by the order of test execution.
1273 1295
 URLconf configuration
1274 1296
 ~~~~~~~~~~~~~~~~~~~~~
1275 1297
 
1276  
-.. attribute:: TestCase.urls
  1298
+.. attribute:: SimpleTestCase.urls
1277 1299
 
1278 1300
 If your application provides views, you may want to include tests that use the
1279 1301
 test client to exercise those views. However, an end user is free to deploy the
@@ -1282,9 +1304,9 @@ tests can't rely upon the fact that your views will be available at a
1282 1304
 particular URL.
1283 1305
 
1284 1306
 In order to provide a reliable URL space for your test,
1285  
-``django.test.TestCase`` provides the ability to customize the URLconf
  1307
+``django.test.*TestCase`` classes provide the ability to customize the URLconf
1286 1308
 configuration for the duration of the execution of a test suite. If your
1287  
-``TestCase`` instance defines an ``urls`` attribute, the ``TestCase`` will use
  1309
+``*TestCase`` instance defines an ``urls`` attribute, the ``*TestCase`` will use
1288 1310
 the value of that attribute as the :setting:`ROOT_URLCONF` for the duration
1289 1311
 of that test.
1290 1312
 
@@ -1307,7 +1329,7 @@ URLconf for the duration of the test case.
1307 1329
 Multi-database support
1308 1330
 ~~~~~~~~~~~~~~~~~~~~~~
1309 1331
 
1310  
-.. attribute:: TestCase.multi_db
  1332
+.. attribute:: TransactionTestCase.multi_db
1311 1333
 
1312 1334
 Django sets up a test database corresponding to every database that is
1313 1335
 defined in the :setting:`DATABASES` definition in your settings
@@ -1340,12 +1362,12 @@ This test case will flush *all* the test databases before running
1340 1362
 Overriding settings
1341 1363
 ~~~~~~~~~~~~~~~~~~~
1342 1364
 
1343  
-.. method:: TestCase.settings
  1365
+.. method:: SimpleTestCase.settings
1344 1366
 
1345 1367
 For testing purposes it's often useful to change a setting temporarily and
1346 1368
 revert to the original value after running the testing code. For this use case
1347 1369
 Django provides a standard Python context manager (see :pep:`343`)
1348  
-:meth:`~django.test.TestCase.settings`, which can be used like this::
  1370
+:meth:`~django.test.SimpleTestCase.settings`, which can be used like this::
1349 1371
 
1350 1372
     from django.test import TestCase
1351 1373
 
@@ -1435,8 +1457,8 @@ MEDIA_ROOT, DEFAULT_FILE_STORAGE Default file storage
1435 1457
 Emptying the test outbox
1436 1458
 ~~~~~~~~~~~~~~~~~~~~~~~~
1437 1459
 
1438  
-If you use Django's custom ``TestCase`` class, the test runner will clear the
1439  
-contents of the test email outbox at the start of each test case.
  1460
+If you use any of Django's custom ``TestCase`` classes, the test runner will
  1461
+clear thecontents of the test email outbox at the start of each test case.
1440 1462
 
1441 1463
 For more detail on email services during tests, see `Email services`_ below.
1442 1464
 
@@ -1486,8 +1508,22 @@ your test suite.
1486 1508
 
1487 1509
         self.assertFieldOutput(EmailField, {'a@a.com': 'a@a.com'}, {'aaa': [u'Enter a valid email address.']})
1488 1510
 
  1511
+.. method:: SimpleTestCase.assertFormError(response, form, field, errors, msg_prefix='')
  1512
+
  1513
+    Asserts that a field on a form raises the provided list of errors when
  1514
+    rendered on the form.
  1515
+
  1516
+    ``form`` is the name the ``Form`` instance was given in the template
  1517
+    context.
  1518
+
  1519
+    ``field`` is the name of the field on the form to check. If ``field``
  1520
+    has a value of ``None``, non-field errors (errors you can access via
  1521
+    ``form.non_field_errors()``) will be checked.
  1522
+
  1523
+    ``errors`` is an error string, or a list of error strings, that are
  1524
+    expected as a result of form validation.
1489 1525
 
1490  
-.. method:: TestCase.assertContains(response, text, count=None, status_code=200, msg_prefix='', html=False)
  1526
+.. method:: SimpleTestCase.assertContains(response, text, count=None, status_code=200, msg_prefix='', html=False)
1491 1527
 
1492 1528
     Asserts that a ``Response`` instance produced the given ``status_code`` and
1493 1529
     that ``text`` appears in the content of the response. If ``count`` is
@@ -1499,7 +1535,7 @@ your test suite.
1499 1535
     attribute ordering is not significant. See
1500 1536
     :meth:`~SimpleTestCase.assertHTMLEqual` for more details.
1501 1537
 
1502  
-.. method:: TestCase.assertNotContains(response, text, status_code=200, msg_prefix='', html=False)
  1538
+.. method:: SimpleTestCase.assertNotContains(response, text, status_code=200, msg_prefix='', html=False)
1503 1539
 
1504 1540
     Asserts that a ``Response`` instance produced the given ``status_code`` and
1505 1541
     that ``text`` does not appears in the content of the response.
@@ -1510,22 +1546,7 @@ your test suite.
1510 1546
     attribute ordering is not significant. See
1511 1547
     :meth:`~SimpleTestCase.assertHTMLEqual` for more details.
1512 1548
 
1513  
-.. method:: TestCase.assertFormError(response, form, field, errors, msg_prefix='')
1514  
-
1515  
-    Asserts that a field on a form raises the provided list of errors when
1516  
-    rendered on the form.
1517  
-
1518  
-    ``form`` is the name the ``Form`` instance was given in the template
1519  
-    context.
1520  
-
1521  
-    ``field`` is the name of the field on the form to check. If ``field``
1522  
-    has a value of ``None``, non-field errors (errors you can access via
1523  
-    ``form.non_field_errors()``) will be checked.
1524  
-
1525  
-    ``errors`` is an error string, or a list of error strings, that are
1526  
-    expected as a result of form validation.
1527  
-
1528  
-.. method:: TestCase.assertTemplateUsed(response, template_name, msg_prefix='')
  1549
+.. method:: SimpleTestCase.assertTemplateUsed(response, template_name, msg_prefix='')
1529 1550
 
1530 1551
     Asserts that the template with the given name was used in rendering the
1531 1552
     response.
@@ -1539,15 +1560,15 @@ your test suite.
1539 1560
         with self.assertTemplateUsed(template_name='index.html'):
1540 1561
             render_to_string('index.html')
1541 1562
 
1542  
-.. method:: TestCase.assertTemplateNotUsed(response, template_name, msg_prefix='')
  1563
+.. method:: SimpleTestCase.assertTemplateNotUsed(response, template_name, msg_prefix='')
1543 1564
 
1544 1565
     Asserts that the template with the given name was *not* used in rendering
1545 1566
     the response.
1546 1567
 
1547 1568
     You can use this as a context manager in the same way as
1548  
-    :meth:`~TestCase.assertTemplateUsed`.
  1569
+    :meth:`~SimpleTestCase.assertTemplateUsed`.
1549 1570
 
1550  
-.. method:: TestCase.assertRedirects(response, expected_url, status_code=302, target_status_code=200, msg_prefix='')
  1571
+.. method:: SimpleTestCase.assertRedirects(response, expected_url, status_code=302, target_status_code=200, msg_prefix='')
1551 1572
 
1552 1573
     Asserts that the response return a ``status_code`` redirect status, it
1553 1574
     redirected to ``expected_url`` (including any GET data), and the final
@@ -1557,44 +1578,6 @@ your test suite.
1557 1578
     ``target_status_code`` will be the url and status code for the final
1558 1579
     point of the redirect chain.
1559 1580
 
1560  
-.. method:: TestCase.assertQuerysetEqual(qs, values, transform=repr, ordered=True)
1561  
-
1562  
-    Asserts that a queryset ``qs`` returns a particular list of values ``values``.
1563  
-
1564  
-    The comparison of the contents of ``qs`` and ``values`` is performed using
1565  
-    the function ``transform``; by default, this means that the ``repr()`` of
1566  
-    each value is compared. Any other callable can be used if ``repr()`` doesn't
1567  
-    provide a unique or helpful comparison.
1568  
-
1569  
-    By default, the comparison is also ordering dependent. If ``qs`` doesn't
1570  
-    provide an implicit ordering, you can set the ``ordered`` parameter to
1571  
-    ``False``, which turns the comparison into a Python set comparison.
1572  
-
1573  
-    .. versionchanged:: 1.6
1574  
-
1575  
-        The method now checks for undefined order and raises ``ValueError``
1576  
-        if undefined order is spotted. The ordering is seen as undefined if
1577  
-        the given ``qs`` isn't ordered and the comparison is against more
1578  
-        than one ordered values.
1579  
-
1580  
-.. method:: TestCase.assertNumQueries(num, func, *args, **kwargs)
1581  
-
1582  
-    Asserts that when ``func`` is called with ``*args`` and ``**kwargs`` that
1583  
-    ``num`` database queries are executed.
1584  
-
1585  
-    If a ``"using"`` key is present in ``kwargs`` it is used as the database
1586  
-    alias for which to check the number of queries.  If you wish to call a
1587  
-    function with a ``using`` parameter you can do it by wrapping the call with
1588  
-    a ``lambda`` to add an extra parameter::
1589  
-
1590  
-        self.assertNumQueries(7, lambda: my_function(using=7))
1591  
-
1592  
-    You can also use this as a context manager::
1593  
-
1594  
-        with self.assertNumQueries(2):
1595  
-            Person.objects.create(name="Aaron")
1596  
-            Person.objects.create(name="Daniel")
1597  
-
1598 1581
 .. method:: SimpleTestCase.assertHTMLEqual(html1, html2, msg=None)
1599 1582
 
1600 1583
     Asserts that the strings ``html1`` and ``html2`` are equal. The comparison
@@ -1624,6 +1607,8 @@ your test suite.
1624 1607
     ``html1`` and ``html2`` must be valid HTML. An ``AssertionError`` will be
1625 1608
     raised if one of them cannot be parsed.
1626 1609
 
  1610
+    Output in case of error can be customized with the ``msg`` argument.
  1611
+
1627 1612
 .. method:: SimpleTestCase.assertHTMLNotEqual(html1, html2, msg=None)
1628 1613
 
1629 1614
     Asserts that the strings ``html1`` and ``html2`` are *not* equal. The
@@ -1633,6 +1618,8 @@ your test suite.
1633 1618
     ``html1`` and ``html2`` must be valid HTML. An ``AssertionError`` will be
1634 1619
     raised if one of them cannot be parsed.
1635 1620
 
  1621
+    Output in case of error can be customized with the ``msg`` argument.
  1622
+
1636 1623
 .. method:: SimpleTestCase.assertXMLEqual(xml1, xml2, msg=None)
1637 1624
 
1638 1625
     .. versionadded:: 1.5
@@ -1644,6 +1631,8 @@ your test suite.
1644 1631
     syntax differences. When unvalid XML is passed in any parameter, an
1645 1632
     ``AssertionError`` is always raised, even if both string are identical.
1646 1633
 
  1634
+    Output in case of error can be customized with the ``msg`` argument.
  1635
+
1647 1636
 .. method:: SimpleTestCase.assertXMLNotEqual(xml1, xml2, msg=None)
1648 1637
 
1649 1638
     .. versionadded:: 1.5
@@ -1652,6 +1641,68 @@ your test suite.
1652 1641
     comparison is based on XML semantics. See
1653 1642
     :meth:`~SimpleTestCase.assertXMLEqual` for details.
1654 1643
 
  1644
+    Output in case of error can be customized with the ``msg`` argument.
  1645
+
  1646
+.. method:: SimpleTestCase.assertInHTML(needle, haystack, count=None, msg_prefix='')
  1647
+
  1648
+    .. versionadded:: 1.5
  1649
+
  1650
+    Asserts that the HTML fragment ``needle`` is contained in the ``haystack`` one.
  1651
+
  1652
+    If the ``count`` integer argument is specified, then additionally the number
  1653
+    of ``needle`` occurrences will be strictly verified.
  1654
+
  1655
+    Whitespace in most cases is ignored, and attribute ordering is not
  1656
+    significant. The passed-in arguments must be valid HTML.
  1657
+
  1658
+.. method:: SimpleTestCase.assertJSONEqual(raw, expected_data, msg=None)
  1659
+
  1660
+    .. versionadded:: 1.5
  1661
+
  1662
+    Asserts that the JSON fragments ``raw`` and ``expected_data`` are equal.
  1663
+    Usual JSON non-significant whitespace rules apply as the heavyweight is
  1664
+    delegated to the :mod:`json` library.
  1665
+
  1666
+    Output in case of error can be customized with the ``msg`` argument.
  1667
+
  1668
+.. method:: TransactionTestCase.assertQuerysetEqual(qs, values, transform=repr, ordered=True)
  1669
+
  1670
+    Asserts that a queryset ``qs`` returns a particular list of values ``values``.
  1671
+
  1672
+    The comparison of the contents of ``qs`` and ``values`` is performed using
  1673
+    the function ``transform``; by default, this means that the ``repr()`` of
  1674
+    each value is compared. Any other callable can be used if ``repr()`` doesn't
  1675
+    provide a unique or helpful comparison.
  1676
+
  1677
+    By default, the comparison is also ordering dependent. If ``qs`` doesn't
  1678
+    provide an implicit ordering, you can set the ``ordered`` parameter to
  1679
+    ``False``, which turns the comparison into a Python set comparison.
  1680
+
  1681
+    .. versionchanged:: 1.6
  1682
+
  1683
+        The method now checks for undefined order and raises ``ValueError``
  1684
+        if undefined order is spotted. The ordering is seen as undefined if
  1685
+        the given ``qs`` isn't ordered and the comparison is against more
  1686
+        than one ordered values.
  1687
+
  1688
+.. method:: TransactionTestCase.assertNumQueries(num, func, *args, **kwargs)
  1689
+
  1690
+    Asserts that when ``func`` is called with ``*args`` and ``**kwargs`` that
  1691
+    ``num`` database queries are executed.
  1692
+
  1693
+    If a ``"using"`` key is present in ``kwargs`` it is used as the database
  1694
+    alias for which to check the number of queries.  If you wish to call a
  1695
+    function with a ``using`` parameter you can do it by wrapping the call with
  1696
+    a ``lambda`` to add an extra parameter::
  1697
+
  1698
+        self.assertNumQueries(7, lambda: my_function(using=7))
  1699
+
  1700
+    You can also use this as a context manager::
  1701
+
  1702
+        with self.assertNumQueries(2):
  1703
+            Person.objects.create(name="Aaron")
  1704
+            Person.objects.create(name="Daniel")
  1705
+
1655 1706
 .. _topics-testing-email:
1656 1707
 
1657 1708
 Email services
@@ -1701,7 +1752,7 @@ and contents::
1701 1752
             self.assertEqual(mail.outbox[0].subject, 'Subject here')
1702 1753
 
1703 1754
 As noted :ref:`previously <emptying-test-outbox>`, the test outbox is emptied
1704  
-at the start of every test in a Django ``TestCase``. To empty the outbox
  1755
+at the start of every test in a Django ``*TestCase``. To empty the outbox
1705 1756
 manually, assign the empty list to ``mail.outbox``::
1706 1757
 
1707 1758
     from django.core import mail

0 notes on commit 0a50311

Please sign in to comment.
Something went wrong with that request. Please try again.