且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Django测试中TestCase和TransactionTestCase类之间的区别

更新时间:2023-11-16 08:11:10

TestCase TransactionTestCase TestCase 包装测试atomic()始终阻止。从文档

The main difference between TestCase and TransactionTestCase is that TestCase wraps the tests with atomic() blocks ALL THE TIME. From the documentation:


将测试包装在两个嵌套的atomic()块中:一个用于整个类,一个用于每个测试

Wraps the tests within two nested atomic() blocks: one for the whole class and one for each test

现在假设您有一个方法,如果该方法未包装在 atomic()块中,则会引发错误。您正在尝试为此进行测试:

Now imagine that you have a method that should raise an error if it is not wrapped inside atomic() block. You are trying to write a test for that:

def test_your_method_raises_error_without_atomic_block(self):
    with self.assertRaises(SomeError):
        your_method()

此测试会意外失败!您猜对了,原因是 TestCase 始终用 atomic()阻止测试。因此, your_method()不会引发错误,因此该测试将失败。在这种情况下,您应该使用TransactionTestCase进行测试。

This test will unexpectedly fail! The reason is, you guessed it, TestCase wraps the tests with atomic() blocks ALL THE TIME. Thus, your_method() will not raise an error, which is why this test will fail. In this case, you should use TransactionTestCase to make your test pass.

select_for_update()很明显:

在支持SELECT ... FOR UPDATE的后端以自动提交模式使用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文档


使用TestCase类,您不能测试代码块是否在事务内执行,这是使用select_for_update()时所必需的

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()的文档,警告:

And if we take a look at the documentation of select_for_update(), we see a warning:


尽管select_for_update()在自动提交模式下通常会失败,因为TestCase自动将每个测试包装在事务中,因此即使在atomic()块之外调用Test_ase中的select_for_update()也将(可能意外地)通过而不会提高一个TransactionManagementError。要正确测试select_for_update(),应使用TransactionTestCase。

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.

希望它会有所帮助!