views:

376

answers:

2

By default when Django runs against sqlite backend it creates a new in memory database for a test. That means for every class that derives from unittest.TestCase, I get a new database. Can this be changed so that it is cleared before every test method is run?

Example: I am testing a manager class that provides additional abstraction on top of Django persistent objects. The code looks more-less like that

class TestForManager(unittest.TestCase):
  def testAddingBlah(self):
    manager = Manager()
    self.assertEquals(manager.getBlahs(), 0)
    manager.addBlah(...)
    self.assertEquals(manager.getBlahs(), 1)

  def testAddingBlahInDifferentWay(self):
    manager = Manager()
    self.assertEquals(manager.getBlahs(), 0)
    manager.addBlahInDifferentWay(...)
    self.assertEquals(manager.getBlahs(), 1)

Now, the first assertion of second test fails, because the state of the database is preserved between test calls and there already is an instance of Blah in the database.

A: 

Why not do the following? This accomplishes what you need without a significant change to your code.

class TestOneForManager(unittest.TestCase):
  def testAddingBlah(self):
    manager = Manager()
    self.assertEquals(manager.getBlahs(), 0)
    manager.addBlah(...)
    self.assertEquals(manager.getBlahs(), 1)

class TestTwoForManager(unittest.TestCase):
  def testAddingBlahInDifferentWay(self):
    manager = Manager()
    self.assertEquals(manager.getBlahs(), 0)
    manager.addBlahInDifferentWay(...)
    self.assertEquals(manager.getBlahs(), 1)


Edit. The "reset on TestCase" feature gives you complete control.

  • Many test methods in a single TestCase are good when you have test cases that don't interfere with each other.

  • Few test methods in a single TestCase are good when you have test cases that interfere with each other.

You can choose which model applies to your tests by grouping your test methods in one or many TestCases. You have total and complete control.

S.Lott
Yeah, I know, I could do that. But it kinda looks weird. It seems good to keep tests for a single class under one unittest.TestCase. I was more looking for some solution that would tune Django to do the right thing.
Marcin
"It seems good to keep tests for a single class under one unittest.TestCase" There's no compelling reason for this. The original unittest design had a single runTest method. One test per Case is fine.
S.Lott
+5  A: 

As always, solution is trivial: use django.test.TestCase not unittest.TestCase. And it works in all major versions of Django!

Marcin