13

I am having little trouble using the python setUpClass.

For example consider the following case

class MyTest(unittest.case.TestCase):

    @classmethod
    def setUpClass(cls):
        print "Test setup"
        try:
            1/0
        except:
            raise

    @classmethod
    def tearDownClass(cls):
        print "Test teardown"

A couple of questions

  1. Is the above code the right way to handle test setUpClass exceptions (by raising it so that the python unittest can take care of it), there are fail(), skip() methods, but those can only be used by test instances and not the test classes.

  2. When there is a setUpClass exception, how can we ensure that tearDownClass runs (unittest doesn't run it, should we manualy call it).

4
  • except: raise does nothing. (Except maybe mess up the stack trace, not sure.) You might as well leave the whole try..except block out. Commented Aug 15, 2012 at 20:47
  • 6
    for your second question: if you think you might raise an exception, then you should use a try..except (like the one you have) to call tearDownClass on an exception. After that, you could reraise the exception. Commented Aug 15, 2012 at 20:49
  • Thanks for the responses, as mentioned by Jeff, the second approach of calling tearDownClass and raising the exception is the solution. Commented Aug 15, 2012 at 21:01
  • 4
    @millimoose, It doesn't mess up the stack trace. That's the point of bare raise. Commented Aug 15, 2012 at 21:11

4 Answers 4

5

You can call tearDownClass on an exception as Jeff points it out, but you may also implements the __del__(cls) method :

import unittest

class MyTest(unittest.case.TestCase):

    @classmethod
    def setUpClass(cls):
        print "Test setup"
        try:
            1/0
        except:
            raise

    @classmethod
    def __del__(cls):
        print "Test teardown"

    def test_hello(cls):
        print "Hello"

if __name__ == '__main__':
    unittest.main()

Will have the following output :

Test setup
E
======================================================================
ERROR: setUpClass (__main__.MyTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "my_test.py", line 8, in setUpClass
    1/0
ZeroDivisionError: integer division or modulo by zero

----------------------------------------------------------------------
Ran 0 tests in 0.000s

FAILED (errors=1)
Test teardown

Note : you should be aware that the __del__ method will be called at the end of the program execution, which is maybe not what you want if you have a more than one test class.

Hope it helps

Sign up to request clarification or add additional context in comments.

Comments

1

The best option would be is to add handler for the except which calls tearDownClass and re-raise exception.

@classmethod
def setUpClass(cls):
    try:
        super(MyTest, cls).setUpClass()
        # setup routine...
    except Exception:  # pylint: disable = W0703
        super(MyTest, cls).tearDownClass()
        raise

Comments

0
import contextlib

class MyTestCase(unitest.TestCase):

    @classmethod
    def setUpClass(cls):
        with contextlib.ExitStack() as stack:
            # ensure teardown is called if error occurs
            stack.callback(cls.tearDownClass)

            # Do the things here!

            # remove callback at the end if no error found
            stack.pop_all()

Comments

0

use tearDownModule. It should be called after setUpClass runs.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.