请解释TestCase
类和TransactionTestCase
类的区别。我已经阅读了文档,但它只是说 TestCase
在数据库事务中运行测试并使用回滚来“撤消”数据库中的测试,如果您需要在测试中手动管理事务,您需要使用 django.test.TransactionTestCase
。
请通过示例帮助我了解实际差异。
TestCase
在什么情况下会失败?回滚是自动发生还是我们必须编写代码来执行回滚?
最佳答案
TestCase
和 TransactionTestCase
之间的主要区别是 TestCase
用 atomic()
block 包装测试 ALL时间。来自documentation :
Wraps the tests within two nested atomic() blocks: one for the whole class and one for each test
现在假设您有一个方法,如果它没有包含在 atomic()
block 中,则应该引发错误。您正在尝试为此编写测试:
def test_your_method_raises_error_without_atomic_block(self):
with self.assertRaises(SomeError):
your_method()
这个测试竟然会失败!原因是,您猜对了,TestCase
始终用 atomic()
block 包装测试。因此,your_method()
不会引发错误,这就是此测试会失败的原因。在这种情况下,您应该使用 TransactionTestCase 让您的测试通过。
select_for_update()是一个明显的例子:
Evaluating a queryset with select_for_update() in autocommit mode on backends which support SELECT ... FOR UPDATE is a TransactionManagementError error
来自TransactionTestCase documentation :
with TestCase class, you cannot test that a block of code is executing within a transaction, as is required when using select_for_update()
如果我们看一下 select_for_update()
的文档,我们会看到一个警告:
Although select_for_update() normally fails in autocommit mode, since TestCase automatically wraps each test in a transaction, calling select_for_update() in a TestCase even outside an atomic() block will (perhaps unexpectedly) pass without raising a TransactionManagementError. To properly test select_for_update() you should use TransactionTestCase.
希望对您有所帮助!
关于python - Django 测试中 TestCase 和 TransactionTestCase 类的区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44450533/