In unittest fixture syntax and flow reference, I only presented fixture methods and functions that threw no exceptions.
However, in real production code, it is entirely possible for something to go wrong when setting up test fixtures.

This post is simply do demonstrate exactly what happens to the flow of your test code when an exception is thrown in a fixture function.

And, while I’m at it, I may as well demo the normal control flow when a test fails, asserts, or throws an exception.

To make the demo code small, I’m going to re-use the code from the previous post, derive my test classes from class TestFixtures (also from that post), and only override one method at a time to show a failure.

If you want to follow along, you’ll want to put this at the top of your file:

from test_fixtures import TestFixtures, setUpModule, tearDownModule

class DemoException(Exception):
    'exception to demostrate fixture/test failures'
    pass

I’m using DemoException to represent a failure in a fixture. However, an assert will be treated the same way.

Let’s look at the following:

General Concept

The general idea is that if a setUp type of method/function fails, then the enclosed tests are NOT run, and the matching tearDown is NOT run.
If a tearDown type of method/function fails, then the only difference from the good case is that the error is noted, and the test fails.

exception in setUp()

The module and class level fixtures are called, just as they would in good cases.
We see setUp being called for both tests.
Since setUp is failing, neither of the tests are run.
And the tearDown method is not run for either test.

class TestExceptionInSetUp(TestFixtures):
    def setUp(self):
        TestFixtures.setUp(self)
        raise DemoException

Output

>python -m unittest -q test_fixture_failure.TestExceptionInSetUp
in module test_fixtures - setUpModule()
in class TestExceptionInSetUp - setUpClass()
in test_1 - setUp()
in test_2 - setUp()
in class TestExceptionInSetUp - tearDownClass()
in module test_fixtures - tearDownModule()
======================================================================
ERROR: test_1 (test_fixture_failure.TestExceptionInSetUp)
a test
----------------------------------------------------------------------
Traceback (most recent call last):
  File "test_fixture_failure.py", line 22, in setUp
    raise DemoException
DemoException

======================================================================
ERROR: test_2 (test_fixture_failure.TestExceptionInSetUp)
another test
----------------------------------------------------------------------
Traceback (most recent call last):
  File "test_fixture_failure.py", line 22, in setUp
    raise DemoException
DemoException

----------------------------------------------------------------------
Ran 2 tests in 0.014s

FAILED (errors=2)

exception in tearDown()

The flow looks identical to a successful test case, but the tearDown exception causes both tests to fail.

class TestExceptionInTearDown(TestFixtures):
    def tearDown(self):
        TestFixtures.tearDown(self)
        raise DemoException

Output

>python -m unittest -q test_fixture_failure.TestExceptionInTearDown
in module test_fixtures - setUpModule()
in class TestExceptionInTearDown - setUpClass()
in test_1 - setUp()
in test_1 - test_1()
in test_1 - tearDown()
in test_2 - setUp()
in test_2 - test_2()
in test_2 - tearDown()
in class TestExceptionInTearDown - tearDownClass()
in module test_fixtures - tearDownModule()
======================================================================
ERROR: test_1 (test_fixture_failure.TestExceptionInTearDown)
a test
----------------------------------------------------------------------
Traceback (most recent call last):
  File "test_fixture_failure.py", line 27, in tearDown
    raise DemoException
DemoException

======================================================================
ERROR: test_2 (test_fixture_failure.TestExceptionInTearDown)
another test
----------------------------------------------------------------------
Traceback (most recent call last):
  File "test_fixture_failure.py", line 27, in tearDown
    raise DemoException
DemoException

----------------------------------------------------------------------
Ran 2 tests in 0.020s

FAILED (errors=2)

exception in setUpClass()

Module fixtures are run normally, but nothing else.

class TestExceptionInSetUpClass(TestFixtures):
    @classmethod
    def setUpClass(cls):
        TestFixtures.setUpClass()
        raise DemoException

Output

>python -m unittest -q test_fixture_failure.TestExceptionInSetUpClass
in module test_fixtures - setUpModule()
in class TestFixtures - setUpClass()
in module test_fixtures - tearDownModule()
======================================================================
ERROR: setUpClass (test_fixture_failure.TestExceptionInSetUpClass)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "test_fixture_failure.py", line 11, in setUpClass
    raise DemoException
DemoException

----------------------------------------------------------------------
Ran 0 tests in 0.010s

FAILED (errors=1)

exception in tearDownClass()

Full test flow as in normal good tests, but the error is noted, and the test fails.

class TestExceptionInTearDownClass(TestFixtures):
    @classmethod
    def tearDownClass(cls):
        TestFixtures.tearDownClass()
        raise DemoException

Output

>python -m unittest -q test_fixture_failure.TestExceptionInTearDownClass
in module test_fixtures - setUpModule()
in class TestExceptionInTearDownClass - setUpClass()
in test_1 - setUp()
in test_1 - test_1()
in test_1 - tearDown()
in test_2 - setUp()
in test_2 - test_2()
in test_2 - tearDown()
in class TestFixtures - tearDownClass()
in module test_fixtures - tearDownModule()
======================================================================
ERROR: tearDownClass (test_fixture_failure.TestExceptionInTearDownClass)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "test_fixture_failure.py", line 17, in tearDownClass
    raise DemoException
DemoException

----------------------------------------------------------------------
Ran 2 tests in 0.020s

FAILED (errors=1)

exception in setUpModule()

To demostrate failure in module functions, I found it easiest just to copy the original test_fixtures.py file, and modify the setUpModule (or tearDownModule).

Not surprisingly, once setUpModule() hits the exception, nothing else is run.
The tearDownModule() is also not run, and the test records one error, and fails the test.

def setUpModule():
    'called once, before anything else in this module'
    logPoint('module %s' % __name__)
    raise DemoException

Output

> python -m unittest -q test_setUpModule_fail.TestFixtures
in module test_setUpModule_fail - setUpModule()
======================================================================
ERROR: setUpModule (test_setUpModule_fail)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "test_setUpModule_fail.py", line 22, in setUpModule
    raise DemoException
DemoException

----------------------------------------------------------------------
Ran 0 tests in 0.006s

FAILED (errors=1)

exception in tearDownModule()

Since tearDownModule() is the last thing to be called when just running one module of tests, we see that all of the flow looks just like the good case. However, unittest does recognize the error, and fails the overall result.

def tearDownModule():
    'called once, after everything else in this module'
    logPoint('module %s' % __name__)
    raise DemoException

Output

> python -m unittest -q test_tearDownModule_fail.TestFixtures
in module test_tearDownModule_fail - setUpModule()
in class TestFixtures - setUpClass()
in test_1 - setUp()
in test_1 - test_1()
in test_1 - tearDown()
in test_2 - setUp()
in test_2 - test_2()
in test_2 - tearDown()
in class TestFixtures - tearDownClass()
in module test_tearDownModule_fail - tearDownModule()
======================================================================
ERROR: tearDownModule (test_tearDownModule_fail)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "test_tearDownModule_fail.py", line 26, in tearDownModule
    raise DemoException
DemoException

----------------------------------------------------------------------
Ran 2 tests in 0.019s

FAILED (errors=1)

failure in a test

For test failures, asserts, and exceptions, I just wanted to demonstrate that all of the test fixtures are run, regardless of the test method outcome.

class TestFailInTest(TestFixtures):
    def test_1(self):
        TestFixtures.test_1(self)
        self.fail()

Output

> python -m unittest -q test_fixture_failure.TestFailInTest
in module test_fixtures - setUpModule()
in class TestFailInTest - setUpClass()
in test_1 - setUp()
in test_1 - test_1()
in test_1 - tearDown()
in test_2 - setUp()
in test_2 - test_2()
in test_2 - tearDown()
in class TestFailInTest - tearDownClass()
in module test_fixtures - tearDownModule()
======================================================================
FAIL: test_1 (test_fixture_failure.TestFailInTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "test_fixture_failure.py", line 37, in test_1
    self.fail()
AssertionError: None

----------------------------------------------------------------------
Ran 2 tests in 0.019s

FAILED (failures=1)

assert in a test

class TestAssertInTest(TestFixtures):
    def test_1(self):
        TestFixtures.test_1(self)
        assert False

Output

> python -m unittest -q test_fixture_failure.TestAssertInTest
in module test_fixtures - setUpModule()
in class TestAssertInTest - setUpClass()
in test_1 - setUp()
in test_1 - test_1()
in test_1 - tearDown()
in test_2 - setUp()
in test_2 - test_2()
in test_2 - tearDown()
in class TestAssertInTest - tearDownClass()
in module test_fixtures - tearDownModule()
======================================================================
FAIL: test_1 (test_fixture_failure.TestAssertInTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "test_fixture_failure.py", line 42, in test_1
    assert False
AssertionError

----------------------------------------------------------------------
Ran 2 tests in 0.020s

FAILED (failures=1)

exception in a test

class TestExceptionInTest(TestFixtures):
    def test_1(self):
        TestFixtures.test_1(self)
        raise DemoException

Output

>python -m unittest -q test_fixture_failure.TestExceptionInTest
in module test_fixtures - setUpModule()
in class TestExceptionInTest - setUpClass()
in test_1 - setUp()
in test_1 - test_1()
in test_1 - tearDown()
in test_2 - setUp()
in test_2 - test_2()
in test_2 - tearDown()
in class TestExceptionInTest - tearDownClass()
in module test_fixtures - tearDownModule()
======================================================================
ERROR: test_1 (test_fixture_failure.TestExceptionInTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "test_fixture_failure.py", line 32, in test_1
    raise DemoException
DemoException

----------------------------------------------------------------------
Ran 2 tests in 0.020s

FAILED (errors=1)

Feedback

As always, let me know if any of this info is incorrect or misleading.

Cheers.