看起来每当我在测试用例中使用 transaction.set_autocommit(False) 时,我都会得到以下堆栈跟踪:

    transaction.set_autocommit(False)
  File "/Users/btoueg/src/python/python3.3.3_django1.6.1/lib/python3.3/site-packages/django/db/transaction.py", line 133, in set_autocommit
    return get_connection(using).set_autocommit(autocommit)
  File "/Users/btoueg/src/python/python3.3.3_django1.6.1/lib/python3.3/site-packages/django/db/backends/__init__.py", line 331, in set_autocommit
    self.validate_no_atomic_block()
  File "/Users/btoueg/src/python/python3.3.3_django1.6.1/lib/python3.3/site-packages/django/db/backends/__init__.py", line 360, in validate_no_atomic_block
    "This is forbidden when an 'atomic' block is active.")
django.db.transaction.TransactionManagementError: This is forbidden when an 'atomic' block is active.

这是正常行为吗?看起来 Django 的 TestCase 类出于性能原因将每个测试包装在一个事务中。

所以问题是: 如果我的代码已经在使用事务,我该如何在 Django 测试用例中测试它?

我将 Django 1.6 与 PostgreSQL 9.2 一起使用

最佳答案

Django TestCase 继承自 TransactionTestCase

根据文档, TestCaseTransactionTestCase 基本相同,但每个测试都包含一个事务(...)。如果您需要在测试中进行事务管理,则必须使用 TransactionTestCase

我的情况有点不同,因为我的测试类是从 DRF APITestCase 派生的。因此,为了在我的测试用例中检查事务管理,我执行了以下操作:

from rest_framework.test import APITestCase
from django.test import TestCase

class MyTestCase(APITestCase):

    def _fixture_setup(self):
        super(TestCase, self)._fixture_setup()

    def _fixture_teardown(self):
        super(TestCase, self)._fixture_teardown()

    ...

关于Django、PostgreSQL、set_autocommit 和测试用例,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22235416/

10-14 16:29
查看更多