Difference between TestCase and TransactionTestCase classes in django test

后端 未结 2 1496
遥遥无期
遥遥无期 2021-02-19 04:32

Please explain the difference between the TestCase class and TransactionTestCase class. I have read the documentation but it\'s only saying that

2条回答
  •  说谎
    说谎 (楼主)
    2021-02-19 04:48

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

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

    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()
    

    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() is a clear case in point:

    Evaluating a queryset with select_for_update() in autocommit mode on backends which support SELECT ... FOR UPDATE is a TransactionManagementError error

    From the 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()

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

    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.

    Hope it helps!

提交回复
热议问题