Django 测试 commit_on_success

Django testing commit_on_success

我有一个函数,我已经包装在 @transaction.commit_on_success 和 运行 Django 单元测试中。

函数太长无法粘贴,部分伪代码为:

@transaction.commit_on_success
def func():
  order = Order.create()
  order.save()
  OrderItem.create(order=order)
  test = 10/0 # make sure we run into an error

然后在我的单元测试中我检查是否 len(Order.objects.all()) == 0

我的函数正在返回一个有效的订单对象,因此事务正在提交。

我做错了什么?

编辑:我使用的是 Django 1.5

如果您使用 MySQL,您的 table 可能不支持交易。有关详细信息,请参阅 transactions 上的 Django 文档。

您应该改用 @transaction.atomic,commit_on_success 自 django 1.6 以来已贬值,因为它不可靠。

有关更多信息,请查看此答案:Is "transaction.atomic" same as "transaction.commit_on_success"?

编辑(因为您使用的是 1.5):

一个可能的解决方法是使用 @transaction.commit_manually,如下所示:https://docs.djangoproject.com/en/1.5/topics/db/transactions/#django.db.transaction.commit_manually

想通了。

我需要使用 TransactionTestCase(没有 1.5 的文档)。

A TransactionTestCase may call commit and rollback and observe the effects of these calls on the database.

我之前曾 运行 遇到过这个问题,但我试图将它与 TestCase 结合使用。它们是互斥的,您的单元测试只能使用其中一个。因为我们使用的是自定义测试 class,我不得不进行一些操作,但现在一切都正常回滚。

看起来 Django 1.8 TestCase 现在也支持事务测试了:

In older versions of Django, the effects of transaction commit and rollback could not be tested within a TestCase. With the completion of the deprecation cycle of the old-style transaction management in Django 1.8, transaction management commands (e.g. transaction.commit()) are no longer disabled within TestCase.

感谢 John 和 siracoj 的回答。无论如何我最好从 1.5 升级 ;)