Класс TransactionTestCase
Класс TransactionTestCase является подклассом TestCase и предназначен для тестирования сценариев, связанных с транзакциями базы данных. В отличие от обычного TestCase, который оборачивает каждый тест в транзакцию и откатывает её после выполнения, TransactionTestCase не использует транзакционную обёртку. Это позволяет проверять поведение кода при работе с реальными транзакциями, включая их фиксацию и откат. Основные параметры класса включают available_apps для ограничения набора приложений при сбросе базы данных, databases для указания используемых баз данных и serialized_rollback для управления откатом данных между тестами.
Особенности работы
Основное отличие TransactionTestCase от TestCase заключается в том, что каждый тестовый метод выполняется в отдельной транзакции, но изменения в базе данных фиксируются. После завершения теста база данных сбрасывается до исходного состояния с помощью усечения таблиц или перезагрузки данных. Это делает TransactionTestCase более медленным, но необходимым для тестирования транзакционной логики.
Синтаксис
from django.test import TransactionTestCase
class MyTransactionTest(TransactionTestCase):
def test_transaction_logic(self):
# Тестовый код
pass
Пример . С откатом транзакции
Давайте проверим, что транзакция откатывается при возникновении исключения:
from django.test import TransactionTestCase
from django.db import transaction
from myapp.models import Article
class TransactionTest(TransactionTestCase):
def test_transaction_rollback(self):
with self.assertRaises(Exception):
with transaction.atomic():
Article.objects.create(title="Test Article")
raise Exception("Rollback test")
# Проверяем, что статья не была создана
count = Article.objects.count()
self.assertEqual(count, 0)
Результат выполнения кода:
"Test passed"
Пример . С фиксацией транзакции
Рассмотрим сценарий, где транзакция успешно фиксируется:
from django.test import TransactionTestCase
from django.db import transaction
from myapp.models import Article
class TransactionCommitTest(TransactionTestCase):
def test_transaction_commit(self):
with transaction.atomic():
article = Article.objects.create(title="Saved Article")
# Проверяем, что статья была создана
count = Article.objects.count()
self.assertEqual(count, 1)
self.assertEqual(article.title, "Saved Article")
Результат выполнения кода:
"Test passed"
Использование setUp
Метод setUp в TransactionTestCase выполняется перед каждым тестом и не является транзакционным. Изменения, сделанные в setUp, будут зафиксированы, как и в основном тесте:
from django.test import TransactionTestCase
from myapp.models import Article
class SetUpTransactionTest(TransactionTestCase):
def setUp(self):
Article.objects.create(title="SetUp Article")
def test_setup_data_exists(self):
count = Article.objects.count()
self.assertEqual(count, 1)
def test_another_test_also_sees_data(self):
count = Article.objects.count()
self.assertEqual(count, 1)
Результат выполнения кода:
"Tests passed"
Смотрите также
-
класс
TestCase,
который используется для стандартных тестов с автоматическим откатом транзакций -
класс
SimpleTestCase,
который предназначен для тестов без взаимодействия с базой данных -
класс
LiveServerTestCase,
который запускает живой сервер для тестирования с внешними инструментами -
метод
setUpTestData,
который создаёт данные один раз для всех тестов в классе