Djangoユニットテストクラス-TestCaseとTransactionTestCase
3837 ワード
TestCaseとTransactionTestCaseはいずれもSimpleTestCaseから継承されており、両者の主な違いは: TestCaseはテスト開始時に、現在接続されているデータベースがトランザクション特性をサポートしているかどうかを判断し、サポートされている場合はトランザクション操作を開始する.テストの終了時にも、サポートなどのトランザクションプロパティがサポートされているかどうかを判断し、トランザクションロールバックを実行し、すべてのリンクを閉じます.具体的なsetuUpClassとtearDownClassの方法は以下の である. TransactionTestCaseはTestCaseとは異なり、このテストクラスではトランザクションブロックは開かれず、テスト終了時にFush操作でデータをクリアします.このようなSimpleTestCaseを書き換えていないsetupとtearDownの方法は、変更されただけです.post_teardownなどは以下の通り:
トランザクションの違いにより、TestCaseを使用する場合、テストされたコードにトランザクションブロックで実行する必要があるコードが表示されると、公式の例のselect_のような例外が放出されます.for_update():
最初のTestCaseは例外を放出します.
2番目のTTCはテストに合格します.
TestCaseは、後続のコードが1つの外部トランザクションのBlock内で実行されることに相当するため、テスト者は、トランザクションBlockで実行する必要があるコード(For instance,you cannot test that a block of code is executing within a transaction,as is required when using select_for_update() をテストすることはできません. TestCaseでは、最終トランザクションをロールバックする必要があるため、conn.close()のようなテストコードの操作を行うと、例外が発生します. TransactionTestCaseはトランザクションを開始せず、テスト終了時のFlush DBのシナリオによってクリーン環境 を復元する.
@classmethod
def setUpClass(cls):
super(TestCase, cls).setUpClass()
if not connections_support_transactions(): #
return
cls.cls_atomics = cls._enter_atomics() # ,TestCase Block
if cls.fixtures:
for db_name in cls._databases_names(include_mirrors=False):
try:
call_command('loaddata', *cls.fixtures, **{
'verbosity': 0,
'commit': False,
'database': db_name,
})
except Exception:
cls._rollback_atomics(cls.cls_atomics)
raise
cls.setUpTestData()
@classmethod
def tearDownClass(cls):
if connections_support_transactions(): #
cls._rollback_atomics(cls.cls_atomics) #
for conn in connections.all(): #
conn.close()
super(TestCase, cls).tearDownClass()
def _post_teardown(self):
"""
*
*
"""
try:
self._fixture_teardown()
super(TransactionTestCase, self)._post_teardown()
if self._should_reload_connections():
for conn in connections.all():
conn.close()
finally:
if self.available_apps is not None:
apps.unset_available_apps()
setting_changed.send(sender=settings._wrapped.__class__,
setting='INSTALLED_APPS',
value=settings.INSTALLED_APPS,
enter=False)
def _fixture_teardown(self):
for db_name in self._databases_names(include_mirrors=False):
call_command('flush', verbosity=0, interactive=False,
database=db_name, reset_sequences=False,
allow_cascade=self.available_apps is not None,
inhibit_post_migrate=self.available_apps is not None)
トランザクションの違いにより、TestCaseを使用する場合、テストされたコードにトランザクションブロックで実行する必要があるコードが表示されると、公式の例のselect_のような例外が放出されます.for_update():
class SampleTestCase(TestCase):
def setUp(self):
Sample.objects.create(**{'field1': 'value1, 'field2': 'value2'})
def test_difference_testcase(self):
sample = Sample.objects.select_for_update().filter()
print(sample)
class SampleTransactionTestCase(TransactionTestCase):
def setUp(self):
Sample.objects.create(**{'field1': 'value1, 'field2': 'value2'})
def test_difference_transactiontestcase(self):
sample = Sample.objects.select_for_update().filter()
print(sample)
最初のTestCaseは例外を放出します.
AssertionError: TransactionManagementError not raised
2番目のTTCはテストに合格します.