4

I have a function that I've got wrapped in @transaction.commit_on_success and running Django unit tests on it.

The function is too long to paste, but some pseudocode is:

@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

Then in my unit test I check if len(Order.objects.all()) == 0

My function is returning a valid Order object, so the transaction is committing.

What am I doing wrong here?

EDIT: I'm on Django 1.5

grokpot
  • 1,462
  • 20
  • 26

3 Answers3

5

Figured it out.

I need to use TransactionTestCase (no documentation for 1.5).

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

I had run across this before but tried to use it in tandem with TestCase. They are mutually exclusive and your unit test can only use one or another. Because we are using a custom test class, I had to some manuvering, but everything is now rolling back properly.

It also looks like Django 1.8 TestCase now supports transaction testing:

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.

Thank you to John and siracoj for your answers. It's probably best that I upgrade from 1.5 anyways ;)

grokpot
  • 1,462
  • 20
  • 26
1

If you're using MySQL your table may not support transactions. See the Django documentation on transactions for details.

John Percival Hackworth
  • 11,395
  • 2
  • 29
  • 38
1

You should use @transaction.atomic instead, commit_on_success has been depreciated since django 1.6 as it is unreliable.

For more info check out this answer: Is "transaction.atomic" same as "transaction.commit_on_success"?

Edit(since you are using 1.5):

A possible work around for this would be to use the @transaction.commit_manually as shown here: https://docs.djangoproject.com/en/1.5/topics/db/transactions/#django.db.transaction.commit_manually

Community
  • 1
  • 1
siracoj
  • 101
  • 9
  • Our stack is using 1.5. While I could consider upgrading Django, I'd rather try to figure out what's happening in our current version. – grokpot Aug 29 '15 at 23:56
  • Thanks for your edit. I think I'm going to proceed with that strategy. So I'm assuming this is just a bug with commit_on_success? – grokpot Aug 30 '15 at 00:15
  • @grokpot Yea, it's unreliable as it says in the answer that I linked. It's possible that it committed with that error, or failed to rollback – siracoj Aug 30 '15 at 00:18