2

I have one class BaseTest and all tests are extended from it. Tests are located in different modules and packages. setUpClass and tearDownClass methods are executed before each unittest.TestCase class. How can I execute setUp and tearDown only once. Before and after all tests.

this is example of code:

import unittest

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

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

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

module2.py:

class TestOne(BaseTest):
    def test_one(self):
        print("Test One")

class TestTwo(BaseTest):
    def test_two(self):
        print("Test Two")

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

module3.py

class TestThree(BaseTest):
    def test_three(self):
        print("Test Three")


class TestFour(BaseTest):
    def test_four(self):
        print("Test Four")

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

module4.py

class TestFive(BaseTest):
    def test_five(self):
        print("Test Five")

if __name__ == '__main__':
    unittest.main()
Mads Marquart
  • 490
  • 1
  • 7
  • 15
Vadim Kovrizhkin
  • 1,575
  • 4
  • 16
  • 27

2 Answers2

2

I don't think unittest has a facility for universal setup and teardown. You should look into pytest, its fixtures are more powerful.

Ned Batchelder
  • 364,293
  • 75
  • 561
  • 662
2

its possible to do with unittest copy the answer from https://stackoverflow.com/a/64892396/2679740 here

you can do it by defining startTestRun,stopTestRun of unittest.TestResult class.

by adding following code to my tests/__init__.py i managed to achieve it. this code runs only once for all tests(regardless of number of test classes and test files).

def startTestRun(self):
    """
    https://docs.python.org/3/library/unittest.html#unittest.TestResult.startTestRun
    Called once before any tests are executed.

    :return:
    """
    DockerCompose().start()


setattr(unittest.TestResult, 'startTestRun', startTestRun)


def stopTestRun(self):
    """
    https://docs.python.org/3/library/unittest.html#unittest.TestResult.stopTestRun
    Called once after all tests are executed.

    :return:
    """
    DockerCompose().compose.stop()


setattr(unittest.TestResult, 'stopTestRun', stopTestRun)
ismail
  • 368
  • 4
  • 6
  • So how exactly would you get the TestSuite to use your customized TestResult? – Joseph Woolf Dec 30 '20 at 05:44
  • I didn't test this yet, but, from whatI can see from the Phthon3 docs link apported in the source code, and checking how __init__.py works in a question about that here [1], I would say that all the content of __init__.py is included when a package is loaded, setattr() sets the value of an attribute of an object [2] and all the startTestRun is run before any test is run. It makes sense: [1] https://stackoverflow.com/questions/119167/adding-code-to-init-py/119178#119178 [2] https://docs.python.org/3/reference/datamodel.html?highlight=setattr#object.__setattr__ – xCovelus Feb 05 '21 at 10:58