Marcin
Marcin

Reputation: 8004

Cleaning up a database in django before every test method

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.

Upvotes: 29

Views: 24009

Answers (5)

Marcin
Marcin

Reputation: 8004

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

Upvotes: 67

Mamun Hasan
Mamun Hasan

Reputation: 41

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

Upvotes: 1

vestronge
vestronge

Reputation: 19

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)

Upvotes: 0

Amandasaurus
Amandasaurus

Reputation: 60809

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

Upvotes: 2

S.Lott
S.Lott

Reputation: 392070

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.

Upvotes: 0

Related Questions