Syntax of xUnit Fixtures

xUnit fixtures include setup()/teardown() functions for module, function, class, and method scope:

setup_module()/teardown_module()

These run at the beginning and end of a module of tests. They run once each. The module parameter is optional.

setup_function()/teardown_function()

These run before and after top-level test functions that are not methods of a test class. They run multiple times, once for every test function. The function parameter is optional.

setup_class()/teardown_class()

These run before and after a class of tests. They run only once. The class parameter is optional.

setup_method()/teardown_method()

These run before and after test methods that are part of a test class. They run multiple times, once for every test method. The method parameter is optional.

Here is an example of all the xUnit fixtures along with a few test functions:

appendices/xunit/test_xUnit_fixtures.py
 def​ setup_module(module):
 print​(f​'​​\n​​setup_module() for {module.__name__}'​)
 
 
 def​ teardown_module(module):
 print​(f​'teardown_module() for {module.__name__}'​)
 
 
 def​ setup_function(function):
 print​(f​'setup_function() for {function.__name__}'​)
 
 
 def​ teardown_function(function):
 print​(f​'teardown_function() for {function.__name__}'​)
 
 
 def​ test_1():
 print​(​'test_1()'​)
 
 
 def​ test_2():
 print​(​'test_2()'​)
 
 
 class​ TestClass:
  @classmethod
 def​ setup_class(cls):
 print​(f​'setup_class() for class {cls.__name__}'​)
 
  @classmethod
 def​ teardown_class(cls):
 print​(f​'teardown_class() for {cls.__name__}'​)
 
 def​ setup_method(self, method):
 print​(f​'setup_method() for {method.__name__}'​)
 
 def​ teardown_method(self, method):
 print​(f​'teardown_method() for {method.__name__}'​)
 
 def​ test_3(self):
 print​(​'test_3()'​)
 
 def​ test_4(self):
 print​(​'test_4()'​)

I used the parameters to the fixture functions to get the name of the module/function/class/method to pass to the print statement. You don’t have to use the parameter names module, function, cls, and method, but that’s the convention.

Here’s the test session to help visualize the control flow:

 $ ​​cd​​ ​​/path/to/code/appendices/xunit
 $ ​​pytest​​ ​​-s​​ ​​test_xUnit_fixtures.py
 ============ test session starts =============
 plugins: mock-1.6.0, cov-2.5.1
 collected 4 items
 
 test_xUnit_fixtures.py
 setup_module() for test_xUnit_fixtures
 setup_function() for test_1
 test_1()
 .teardown_function() for test_1
 setup_function() for test_2
 test_2()
 .teardown_function() for test_2
 setup_class() for class TestClass
 setup_method() for test_3
 test_3()
 .teardown_method() for test_3
 setup_method() for test_4
 test_4()
 .teardown_method() for test_4
 teardown_class() for TestClass
 teardown_module() for test_xUnit_fixtures
 
 ========== 4 passed in 0.01 seconds ==========