Pages

Monday, 25 April 2011

Calling only once setUp in unittest in python

In python unittest the setUp function gets called every time you need to run a single TestCase (no matter if you run it using TestSuite or simply unittest.main()).

So if you have to test something that requires a complex setUp routine (like loading 50000 records from SQL or preparing an orangemochafrappuccino) but that can be reused all along your TestSuite you have the same problem I had.

Now all around the internet there are posts saying "You could do that" or "One way to do that" or "Once I did that like this..." or even worse "The standard way of doing it is...".

But none of these posts really gets to the bottom of it, they all give you a piece of information. I couldn't find one place that told you "copy/paste this code and be happy".

So, after figuring it out, I can now tell you "copy/paste this code and be happy".
import unittest
from my_program import MyClass

class MyClassTest(unittest.TestCase):
    # First define a class variable that determines 
    # if setUp was ever run
    ClassIsSetup = False

    def setUp(self):
        # If it was not setup yet, do it
        if not self.ClassIsSetup:
            print "Initializing testing environment"
            # run the real setup
            self.setupClass()
            # remember that it was setup already
            self.__class__.ClassIsSetup = True
                               
    def setupClass(self):
        # Do the real setup
        unittest.TestCase.setUp(self)
        # you want to have persistent things to test
        self.__class__.myclass = MyClass()
        # (you can call this later with self.myclass)

You can do the same for the unittest.tearDown since it is exactly the same code.

7 comments:

  1. thanks Stefano,

    this code snipped is exactly what I needed ... and it works beautifully :)

    Rainer

    ReplyDelete
  2. Haha, worked for me too. I searched for this answer and, like yourself, found many partial and incomplete answers.

    ReplyDelete
  3. It just works, thanks!

    ReplyDelete
  4. @classmethod
    def setUpClass(cls):

    ReplyDelete
  5. Hello,

    I am getting error at import unittest, please let me know what i have to do....

    ReplyDelete
    Replies
    1. Read what the error says and try to fix it.

      Delete