test_testcase.py 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136
  1. from functools import wraps
  2. from django.db import IntegrityError, connections, transaction
  3. from django.test import TestCase, ignore_warnings, skipUnlessDBFeature
  4. from django.test.testcases import TestData
  5. from django.utils.deprecation import RemovedInDjango41Warning
  6. from .models import Car, Person, PossessedCar
  7. class TestTestCase(TestCase):
  8. @skipUnlessDBFeature('can_defer_constraint_checks')
  9. @skipUnlessDBFeature('supports_foreign_keys')
  10. def test_fixture_teardown_checks_constraints(self):
  11. rollback_atomics = self._rollback_atomics
  12. self._rollback_atomics = lambda connection: None # noop
  13. try:
  14. car = PossessedCar.objects.create(car_id=1, belongs_to_id=1)
  15. with self.assertRaises(IntegrityError), transaction.atomic():
  16. self._fixture_teardown()
  17. car.delete()
  18. finally:
  19. self._rollback_atomics = rollback_atomics
  20. def test_disallowed_database_connection(self):
  21. message = (
  22. "Database connections to 'other' are not allowed in this test. "
  23. "Add 'other' to test_utils.test_testcase.TestTestCase.databases to "
  24. "ensure proper test isolation and silence this failure."
  25. )
  26. with self.assertRaisesMessage(AssertionError, message):
  27. connections['other'].connect()
  28. with self.assertRaisesMessage(AssertionError, message):
  29. connections['other'].temporary_connection()
  30. def test_disallowed_database_queries(self):
  31. message = (
  32. "Database queries to 'other' are not allowed in this test. "
  33. "Add 'other' to test_utils.test_testcase.TestTestCase.databases to "
  34. "ensure proper test isolation and silence this failure."
  35. )
  36. with self.assertRaisesMessage(AssertionError, message):
  37. Car.objects.using('other').get()
  38. class NonDeepCopyAble:
  39. def __deepcopy__(self, memo):
  40. raise TypeError
  41. def assert_no_queries(test):
  42. @wraps(test)
  43. def inner(self):
  44. with self.assertNumQueries(0):
  45. test(self)
  46. return inner
  47. class TestDataTests(TestCase):
  48. # setUpTestData re-assignment are also wrapped in TestData.
  49. jim_douglas = None
  50. @classmethod
  51. def setUpTestData(cls):
  52. cls.jim_douglas = Person.objects.create(name='Jim Douglas')
  53. cls.car = Car.objects.create(name='1963 Volkswagen Beetle')
  54. cls.herbie = cls.jim_douglas.possessed_cars.create(
  55. car=cls.car,
  56. belongs_to=cls.jim_douglas,
  57. )
  58. cls.non_deepcopy_able = NonDeepCopyAble()
  59. @assert_no_queries
  60. def test_class_attribute_equality(self):
  61. """Class level test data is equal to instance level test data."""
  62. self.assertEqual(self.jim_douglas, self.__class__.jim_douglas)
  63. @assert_no_queries
  64. def test_class_attribute_identity(self):
  65. """
  66. Class level test data is not identical to instance level test data.
  67. """
  68. self.assertIsNot(self.jim_douglas, self.__class__.jim_douglas)
  69. @assert_no_queries
  70. def test_identity_preservation(self):
  71. """Identity of test data is preserved between accesses."""
  72. self.assertIs(self.jim_douglas, self.jim_douglas)
  73. @assert_no_queries
  74. def test_known_related_objects_identity_preservation(self):
  75. """Known related objects identity is preserved."""
  76. self.assertIs(self.herbie.car, self.car)
  77. self.assertIs(self.herbie.belongs_to, self.jim_douglas)
  78. @ignore_warnings(category=RemovedInDjango41Warning)
  79. def test_undeepcopyable(self):
  80. self.assertIs(self.non_deepcopy_able, self.__class__.non_deepcopy_able)
  81. def test_undeepcopyable_warning(self):
  82. msg = (
  83. "Assigning objects which don't support copy.deepcopy() during "
  84. "setUpTestData() is deprecated. Either assign the "
  85. "non_deepcopy_able attribute during setUpClass() or setUp(), or "
  86. "add support for deepcopy() to "
  87. "test_utils.test_testcase.TestDataTests.non_deepcopy_able."
  88. )
  89. with self.assertRaisesMessage(RemovedInDjango41Warning, msg):
  90. self.non_deepcopy_able
  91. def test_repr(self):
  92. self.assertEqual(
  93. repr(TestData('attr', 'value')),
  94. "<TestData: name='attr', data='value'>",
  95. )
  96. class SetupTestDataIsolationTests(TestCase):
  97. """
  98. In-memory data isolation is respected for model instances assigned to class
  99. attributes during setUpTestData.
  100. """
  101. @classmethod
  102. def setUpTestData(cls):
  103. cls.car = Car.objects.create(name='Volkswagen Beetle')
  104. def test_book_name_deutsh(self):
  105. self.assertEqual(self.car.name, 'Volkswagen Beetle')
  106. self.car.name = 'VW sKäfer'
  107. self.car.save()
  108. def test_book_name_french(self):
  109. self.assertEqual(self.car.name, 'Volkswagen Beetle')
  110. self.car.name = 'Volkswagen Coccinelle'
  111. self.car.save()