1. from functools import wraps
    
  2. 
    
  3. from django.db import IntegrityError, connections, transaction
    
  4. from django.test import TestCase, skipUnlessDBFeature
    
  5. from django.test.testcases import DatabaseOperationForbidden, TestData
    
  6. 
    
  7. from .models import Car, Person, PossessedCar
    
  8. 
    
  9. 
    
  10. class TestTestCase(TestCase):
    
  11.     @skipUnlessDBFeature("can_defer_constraint_checks")
    
  12.     @skipUnlessDBFeature("supports_foreign_keys")
    
  13.     def test_fixture_teardown_checks_constraints(self):
    
  14.         rollback_atomics = self._rollback_atomics
    
  15.         self._rollback_atomics = lambda connection: None  # noop
    
  16.         try:
    
  17.             car = PossessedCar.objects.create(car_id=1, belongs_to_id=1)
    
  18.             with self.assertRaises(IntegrityError), transaction.atomic():
    
  19.                 self._fixture_teardown()
    
  20.             car.delete()
    
  21.         finally:
    
  22.             self._rollback_atomics = rollback_atomics
    
  23. 
    
  24.     def test_disallowed_database_connection(self):
    
  25.         message = (
    
  26.             "Database connections to 'other' are not allowed in this test. "
    
  27.             "Add 'other' to test_utils.test_testcase.TestTestCase.databases to "
    
  28.             "ensure proper test isolation and silence this failure."
    
  29.         )
    
  30.         with self.assertRaisesMessage(DatabaseOperationForbidden, message):
    
  31.             connections["other"].connect()
    
  32.         with self.assertRaisesMessage(DatabaseOperationForbidden, message):
    
  33.             connections["other"].temporary_connection()
    
  34. 
    
  35.     def test_disallowed_database_queries(self):
    
  36.         message = (
    
  37.             "Database queries to 'other' are not allowed in this test. "
    
  38.             "Add 'other' to test_utils.test_testcase.TestTestCase.databases to "
    
  39.             "ensure proper test isolation and silence this failure."
    
  40.         )
    
  41.         with self.assertRaisesMessage(DatabaseOperationForbidden, message):
    
  42.             Car.objects.using("other").get()
    
  43. 
    
  44.     @skipUnlessDBFeature("supports_transactions")
    
  45.     def test_reset_sequences(self):
    
  46.         old_reset_sequences = self.reset_sequences
    
  47.         self.reset_sequences = True
    
  48.         msg = "reset_sequences cannot be used on TestCase instances"
    
  49.         try:
    
  50.             with self.assertRaisesMessage(TypeError, msg):
    
  51.                 self._fixture_setup()
    
  52.         finally:
    
  53.             self.reset_sequences = old_reset_sequences
    
  54. 
    
  55. 
    
  56. def assert_no_queries(test):
    
  57.     @wraps(test)
    
  58.     def inner(self):
    
  59.         with self.assertNumQueries(0):
    
  60.             test(self)
    
  61. 
    
  62.     return inner
    
  63. 
    
  64. 
    
  65. # On databases with no transaction support (for instance, MySQL with the MyISAM
    
  66. # engine), setUpTestData() is called before each test, so there is no need to
    
  67. # clone class level test data.
    
  68. @skipUnlessDBFeature("supports_transactions")
    
  69. class TestDataTests(TestCase):
    
  70.     # setUpTestData re-assignment are also wrapped in TestData.
    
  71.     jim_douglas = None
    
  72. 
    
  73.     @classmethod
    
  74.     def setUpTestData(cls):
    
  75.         cls.jim_douglas = Person.objects.create(name="Jim Douglas")
    
  76.         cls.car = Car.objects.create(name="1963 Volkswagen Beetle")
    
  77.         cls.herbie = cls.jim_douglas.possessed_cars.create(
    
  78.             car=cls.car,
    
  79.             belongs_to=cls.jim_douglas,
    
  80.         )
    
  81. 
    
  82.         cls.person_binary = Person.objects.create(name="Person", data=b"binary data")
    
  83.         cls.person_binary_get = Person.objects.get(pk=cls.person_binary.pk)
    
  84. 
    
  85.     @assert_no_queries
    
  86.     def test_class_attribute_equality(self):
    
  87.         """Class level test data is equal to instance level test data."""
    
  88.         self.assertEqual(self.jim_douglas, self.__class__.jim_douglas)
    
  89.         self.assertEqual(self.person_binary, self.__class__.person_binary)
    
  90.         self.assertEqual(self.person_binary_get, self.__class__.person_binary_get)
    
  91. 
    
  92.     @assert_no_queries
    
  93.     def test_class_attribute_identity(self):
    
  94.         """
    
  95.         Class level test data is not identical to instance level test data.
    
  96.         """
    
  97.         self.assertIsNot(self.jim_douglas, self.__class__.jim_douglas)
    
  98.         self.assertIsNot(self.person_binary, self.__class__.person_binary)
    
  99.         self.assertIsNot(self.person_binary_get, self.__class__.person_binary_get)
    
  100. 
    
  101.     @assert_no_queries
    
  102.     def test_binaryfield_data_type(self):
    
  103.         self.assertEqual(bytes(self.person_binary.data), b"binary data")
    
  104.         self.assertEqual(bytes(self.person_binary_get.data), b"binary data")
    
  105.         self.assertEqual(
    
  106.             type(self.person_binary_get.data),
    
  107.             type(self.__class__.person_binary_get.data),
    
  108.         )
    
  109.         self.assertEqual(
    
  110.             type(self.person_binary.data),
    
  111.             type(self.__class__.person_binary.data),
    
  112.         )
    
  113. 
    
  114.     @assert_no_queries
    
  115.     def test_identity_preservation(self):
    
  116.         """Identity of test data is preserved between accesses."""
    
  117.         self.assertIs(self.jim_douglas, self.jim_douglas)
    
  118. 
    
  119.     @assert_no_queries
    
  120.     def test_known_related_objects_identity_preservation(self):
    
  121.         """Known related objects identity is preserved."""
    
  122.         self.assertIs(self.herbie.car, self.car)
    
  123.         self.assertIs(self.herbie.belongs_to, self.jim_douglas)
    
  124. 
    
  125.     def test_repr(self):
    
  126.         self.assertEqual(
    
  127.             repr(TestData("attr", "value")),
    
  128.             "<TestData: name='attr', data='value'>",
    
  129.         )
    
  130. 
    
  131. 
    
  132. class SetupTestDataIsolationTests(TestCase):
    
  133.     """
    
  134.     In-memory data isolation is respected for model instances assigned to class
    
  135.     attributes during setUpTestData.
    
  136.     """
    
  137. 
    
  138.     @classmethod
    
  139.     def setUpTestData(cls):
    
  140.         cls.car = Car.objects.create(name="Volkswagen Beetle")
    
  141. 
    
  142.     def test_book_name_deutsh(self):
    
  143.         self.assertEqual(self.car.name, "Volkswagen Beetle")
    
  144.         self.car.name = "VW sKäfer"
    
  145.         self.car.save()
    
  146. 
    
  147.     def test_book_name_french(self):
    
  148.         self.assertEqual(self.car.name, "Volkswagen Beetle")
    
  149.         self.car.name = "Volkswagen Coccinelle"
    
  150.         self.car.save()