Run setUp only once for a set of automated tests

You can use setUpClass to define methods that only run once per testsuite.


Daniel's answer is correct, but here is an example to avoid some common mistakes I found, such as not calling super() in setUpClass() when TestCase is a subclass of unittest.TestCase (like in django.test or falcon.testing).

The documentation for setUpClass() doesn't mention that you need to call super() in such cases. You will get an error if you don't, as seen in this related question.

class SomeTest(TestCase):
    def setUp(self):
        self.user1 = UserProfile.objects.create_user(resource=SomeTest.the_resource)

    @classmethod
    def setUpClass(cls):
        """ get_some_resource() is slow, to avoid calling it for each test use setUpClass()
            and store the result as class variable
        """
        super(SomeTest, cls).setUpClass()
        cls.the_resource = get_some_resource()

I'm using Python 3 and found that the cls reference is also available in the setup method and so the following works:

class TestThing(unittest.TestCase):

  @classmethod
  def setUpClass(cls):
    cls.thing = Thing() # the `thing` is only instantiated once

  def setup(self):
    self.thing = TestThing.thing # ...but set on each test case instance

  def test_the_thing(self):
    self.assertTrue(self.thing is not None)

setup_done is a class variable, not an instance variable.

You are referencing it as an instance variable:

self.setup_done

But you need to reference it as a class variable:

mySelTest.setup_done

Here's the corrected code:

class mySelTest(unittest.TestCase):
    setup_done = False

    def setUp(self):
        print str(mySelTest.setup_done)

        if mySelTest.setup_done:
            return
        mySelTest.setup_done = True
        print str(mySelTest.setup_done)

If you ended up here because of need to load some data for testing... then as far as you are using Django 1.9+ please go for setUpTestData:

class MyTests(TestCase):

    @classmethod
    def setUpTestData(cls):
        # Set up data for the whole TestCase
        cls.foo = Foo.objects.create(bar="Test")

    def test1(self):
        self.assertEqual(self.foo.bar, 'Test')