2014-03-06 65 views
3

它看起来像每当我在测试情况下使用transaction.set_autocommit(False),我得到以下堆栈跟踪:的Django和PostgreSQL,set_autocommit和测试用例

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

+0

为什么要关闭自动提交? – Louis

+0

有时您需要更细粒度的事务管理。当自动提交打开时,只要插入/更新/删除完成就立即提交。关闭自动提交可让您执行一批自动提交,然后一次全部提交或在发生错误时进行回滚。包裹在原子,作为试验例做,意味着它不提交直到该块的结束,但不允许手动管理提交和回滚。今天我也为此奋斗了几个小时,并没有提出解决方案。 – jmichalicek

回答

4

的Django从TransactionTestCaseTestCase继承。

根据文档,TestCase基本上与TransactionTestCase相同,但是使用事务(...)包围每个测试。你必须使用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() 

    ... 
+0

谢谢,我来到这里后正是约需要用到现在TransactionTestCase。在<1.5 transaction.commit_manually()工作(或似乎至少工作...)在一个普通的TestCase中。我敢肯定,使用TransactionTestCase被一直打算,但该文档并没有说清楚,现在是必需的。 – jmichalicek