The difference manifests itself when you have more than one test method in your class. setUpClass and tearDownClass are run once for the whole class; setUp and tearDown are run before and after each test method.

For example:

class Example(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        print("setUpClass")

    def setUp(self):
        print("setUp")

    def test1(self):
        print("test1")

    def test2(self):
        print("test2")

    def tearDown(self):
        print("tearDown")

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

When you run this test, it prints:

setUpClass
setUp
test1
tearDown
.setUp
test2
tearDown
.tearDownClass

(The dots (.) are unittest's default output when a test passes.) Observe that setUp and tearDown appear before and after test1 and test2, whereas setUpClass and tearDownClass appear only once, at the beginning and end of the whole test case.

Answer from Benjamin Hodgson on Stack Overflow
Top answer
1 of 3
249

The difference manifests itself when you have more than one test method in your class. setUpClass and tearDownClass are run once for the whole class; setUp and tearDown are run before and after each test method.

For example:

class Example(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        print("setUpClass")

    def setUp(self):
        print("setUp")

    def test1(self):
        print("test1")

    def test2(self):
        print("test2")

    def tearDown(self):
        print("tearDown")

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

When you run this test, it prints:

setUpClass
setUp
test1
tearDown
.setUp
test2
tearDown
.tearDownClass

(The dots (.) are unittest's default output when a test passes.) Observe that setUp and tearDown appear before and after test1 and test2, whereas setUpClass and tearDownClass appear only once, at the beginning and end of the whole test case.

2 of 3
35

What is the difference between setUp() and setUpClass() in the Python unittest framework?

The main difference (as noted in the answer by Benjamin Hodgson) is that setUpClass is called only once and that is before all the tests, while setUp is called immediately before each and every test. (NB: The same applies to the equivalent methods in other xUnit test frameworks, not just Python's unittest.)

From the unittest documentation:

setUpClass()

A class method called before tests in an individual class are run. setUpClass is called with the class as the only argument and must be decorated as a classmethod():

@classmethod
def setUpClass(cls):
    ...

and:

setUp()

Method called to prepare the test fixture. This is called immediately before calling the test method; other than AssertionError or SkipTest, any exception raised by this method will be considered an error rather than a test failure. The default implementation does nothing.

Why would setup be handled in one method over the other?

This part of the question has not been answered yet. As per my comment in response to the answer by Gearon, the setUp method is meant for elements of the fixture that are common to all tests (to avoid duplicating that code in each test). I find this is often useful as removing duplication (usually) improves readability and reduces the maintenance burden.

The setUpClass method is for expensive elements that you would rather only have to do once, such as opening a database connection, opening a temporary file on the filesystem, loading a shared library for testing, etc. Doing such things before each test would slow down the test suite too much, so we just do it once before all the tests. This is a slight degradation in the independence of the tests but a necessary optimization in some situations. Arguably, one should not be doing such things in unit tests as it is usually possible to mock the database / filesystem / library / whatever without using the real thing. As such, I find that setUpClass is rarely needed. However, it is useful when testing the above examples (or similar) becomes necessary.

🌐
DZone
dzone.com › testing, deployment, and maintenance › testing, tools, and frameworks › python unit testing: one time initialization
Python Unit Testing: One Time Initialization - DZone
March 17, 2021 - The unit test package allows us to define a setUp method for the class — a class method, namely setUpClass. Similarly, we can define a tearDown method for the class — tearDownClass.
🌐
YouTube
youtube.com › watch
PYTHON : What is the difference between setUp() and setUpClass() in Python unittest? - YouTube
PYTHON : What is the difference between setUp() and setUpClass() in Python unittest? [ Gift : Animated Search Engine : https://www.hows.tech/p/recommended.ht...
Published: December 10, 2021
🌐
Python
docs.python.org › 3 › library › unittest.html
unittest — Unit testing framework
The default implementation does nothing. ... A class method called before tests in an individual class are run. setUpClass is called with the class as the only argument and must be decorated as a @classmethod:
🌐
freeCodeCamp
freecodecamp.org › news › how-to-write-unit-tests-for-instance-methods-in-python
How to Write Unit Tests for Instance Methods in Python
January 31, 2023 - The setUp() and tearDown() methods are executed before and after each test, respectively. Let’s add the setUpClass() and tearDownClass() class methods to the TestBook class. from book import Book import unittest class TestBook(unittest.TestCase): @classmethod def setUpClass(cls): print("\nsetUpClass method: Runs before all tests...") def setUp(self): print("\nRunning setUp method...") self.book_1 = Book('Deep Work','Cal Newport',304,15,0.05) self.book_2 = Book('Grit','Angela Duckworth',447,16,0.15) def tearDown(self): print("Running tearDown method...") def test_reading_time(self): print("Ru
🌐
GitHub
gist.github.com › twolfson › 13f5f5784f67fd49b245
Python unittest `setUp` inheritance · GitHub
In some cases for Python unit tests, we want to automatically perform setUp methods in as declared in a base class. However, we still want setUp to work as per normal in the subclass. The following code will proxy the new setUp function to run it's base class' and the new one. # Define a common test base for starting servers class MyBaseTestCase(unittest.TestCase): @classmethod def setUpClass(cls): """On inherited classes, run our `setUp` method""" # Inspired via http://stackoverflow.com/questions/1323455/python-unit-test-with-base-and-sub-class/17696807#17696807 if cls is not MyBaseTestCase a
Find elsewhere
🌐
Medium
medium.com › an-engineer-a-reader-a-guy › django-test-fixture-setup-setupclass-and-setuptestdata-72b6d944cdef
Django Test Fixture: setUp, setUpClass and setUpTestData | by Nhat Cuong / Nathan | an engineer / a reader / a guy | Medium
March 27, 2020 - The changes you made in setUpClass, you have to clean them later in tearDownClass. This can be complicated, but moreover, you might ask: "Why can't someone do the clean up for me?". You are right, and that's why setUpTestData got into the spotlight. Unlike the previous methods, setUpTestData does not belong to unittest but to the Django framework.
🌐
Dmorgan
dmorgan.info › posts › python-unittest-fixtures
Python unittest Fixtures – dmorgan.info
July 25, 2015 - Class-scope test fixtures provide the common initial conditions for all tests located within the same class. Setup is done in the setUpClass class method and clean up is done in the tearDownClass method.
🌐
pytest
docs.pytest.org › en › stable › how-to › unittest.html
How to use unittest-based tests with pytest - pytest documentation
unittest.TestCase.setUp()/unittest.TestCase.tearDown() unittest.TestCase.setUpClass()/unittest.TestCase.tearDownClass() unittest.setUpModule()/unittest.tearDownModule() unittest.TestCase.subTest() (since version 9.0) Up to this point pytest does not have support for the following features: load_tests protocol; By running your test suite with pytest you can make use of several features, in most cases without having to modify existing code: Obtain more informative tracebacks; stdout and stderr capturing; Test selection options using -k and -m flags; Stopping after the first (or N) failures; –p
🌐
Medium
medium.com › @urkude.nikesh › python-basic-unittest-example-b72b4c9d89cf
Python basic unittest example. Python Unit Test | by Nikesh Urkude | Medium
September 25, 2020 - import unittest class ... methods in python. setUpClass(cls) : This method is used for setting up the mock data or generating test data like for starting servers or opening connections....
🌐
Python Tutorial
pythontutorial.net › home › python unit testing › python test fixtures
Python Test Fixtures
July 9, 2022 - Python (python) In this example, the setUpModule() function runs before all the test methods and the tearDownModule() function runs after all the test methods. The setUpClass() and tearDownClass() are class-level fixtures: The setUpClass() runs before all test methods of a class · The ...
🌐
GitHub
github.com › microsoft › vscode-python › issues › 3252
Run/Debug unittest Method does not run setUpClass · Issue #3252 · microsoft/vscode-python
November 8, 2018 - Relevant/affected Python packages ... being called, but not its setUpClass method; the setUpClass method only gets run if you click the Run Test overlay above the entire test class....
Author: microsoft
🌐
GitHub
github.com › python › mypy › issues › 8723
Support adding class variables to class through assignment · Issue #8723 · python/mypy
April 25, 2020 - However in many cases it's useful to be able to add items to the class during setUpClass (or Django's setUpTestData). import unittest class Tests(unittest.TestCase): @classmethod def setUpClass(cls) -> None: cls.foo = 42 # "Type[Tests]" has no attribute "foo" def test_foo(self) -> None: print(self.foo) # "Tests" has no attribute "foo" Adding a ClassVar allows for a workaround to this, however it would be nice if that wasn't needed.
Author: python
Top answer
1 of 1
4

Maybe this is what @Klaus means?

import unittest


class TestA(unittest.TestCase):
    def setUp(self):
        print "Setup # 1"

    def test1(self):
        print "Doing test1"

class TestB(unittest.TestCase):
    def setUp(self):
        print "Setup # 2"

    def test2(self):
        print "Doing test2"


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

Alternatively you can change setup based on the method name.
Although this might be a bit more of a pain to maintain.

class TestA(unittest.TestCase):
    def setUp(self):
        if self._testMethodName == "test1":
            print "Setup # 1"
        elif self._testMethodName == "test2":
            print "Setup # 2"

    def test1(self):
        print "Doing test1"

    def test2(self):
        print "Doing test2"


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

Both produce the same output:

Output:
Setup # 1
Doing test1
.Setup # 2
Doing test2
.
----------------------------------------------------------------------
Ran 2 tests in 0.001s

OK

EDIT: Sorry, I don't think I fully understand but here is my attempt at implementing your comment. My approach here is to reapply BaseTest.setUp() rather than try to keep it intact as you described.
TypeOneTests and TypeTwoTests inherit BaseTest and they call BaseTest's setUp function inside their own using super(...)

class BaseTest(unittest.TestCase):
    def setUp(self):
        print "BaseTest setUp"

    def tearDown(self):
        print "BaseTest tearDown"

    # you could add tests here but I didn't add any based on your comment


class TypeOneTests(BaseTest):
    def setUp(self):
        super(TypeOneTests, self).setUp()
        print "TypeOneTests setUp"

    def tearDown(self):
        print "TypeOneTests tearDown"

    def test(self):
        print "a test in TypeOneTests"


class TypeTwoTests(BaseTest):
    def setUp(self):
        super(TypeTwoTests, self).setUp()
        print "TypeTwoTests additional setUp"

    def tearDown(self):
        print "TypeTwoTests tearDown"
        super(TypeTwoTests, self).tearDown()

    def test(self):
        print "a test in TypeTwoTests"


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

Output:

BaseTest setUp
TypeOneTests setUp
a test in TypeOneTests
TypeOneTests tearDown
.BaseTest setUp
TypeTwoTests additional setUp
a test in TypeTwoTests
TypeTwoTests tearDown
BaseTest tearDown
.
----------------------------------------------------------------------
Ran 2 tests in 0.002s

OK
🌐
GitHub
github.com › AlexIoannides › pyspark-example-project › issues › 20
Setup and Teardown should be @classmethods setUpClass and tearDownClass · Issue #20 · AlexIoannides/pyspark-example-project
September 16, 2020 - `class PySparkTest(unittest.TestCase): @classmethod def suppress_py4j_logging(cls): logger = logging.getLogger('py4j') logger.setLevel(logging.WARN) @classmethod def create_testing_pyspark_session(cls): return SparkSession \ .builder \ .master('local[*]') \ .appName("my-local-testing-pyspark-context") \ .getOrCreate() @classmethod def setUpClass(cls): cls.suppress_py4j_logging() cls.spark = cls.create_testing_pyspark_session() cls.test_data_path = "<PATH>" cls.df = cls.spark.read.options(header='true', inferSchema='true') \ .csv(cls.test_data_path) cls.df_exepcted = transform_data(cls.df, cls.spark) @classmethod def tearDownClass(cls): cls.spark.stop()`
Author: AlexIoannides