28

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.

Marcin
  • 7,874
  • 7
  • 45
  • 49

5 Answers5

64

Use django.test.TestCase not unittest.TestCase. And it works in all major versions of Django!

Marcin
  • 7,874
  • 7
  • 45
  • 49
2

You can use the tearDown method. It will be called after your test is run. You can delete all Blahs there.

Amandasaurus
  • 58,203
  • 71
  • 188
  • 248
1

Make them in two different functions both are not test function. Finally call the dependent functions from one test function.

0

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
  • 384,516
  • 81
  • 508
  • 779
  • 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 Jan 12 '09 at 13:00
  • "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 Jan 12 '09 at 13:07
0

For clearing non-default databases, add multi_db = True in the class

eg

class MyTestCase(django.test.TestCase)
    multi_db = True

    def test_one(self):
        self.assertTrue(True)
vestronge
  • 21
  • 1