Executing Python Unit Tests: Three Methods Compared

The unittest framework provides several methods for executing tests. simplest approach is to define a test case class that inherits from unittest.TestCase. This class can include setup and teardown methods that run before and after each individual test, as well as class-level setup and teardown that run once for the entire class.

import unittest

class BasicTestSuite(unittest.TestCase):
    @classmethod
    def initialize_class(cls):
        print("Class-level setup")

    @classmethod
    def cleanup_class(cls):
        print("Class-level teardown")

    def initialize_test(self):
        print("Test-level setup")

    def cleanup_test(self):
        print("Test-level teardown")

    def test_uppercase_check(self):
        print('Running uppercase test')
        self.assertTrue('HELLO'.isupper())

    def test_placeholder(self):
        print('Running placeholder test')

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

When executed, the output demonstrates the order of operations:

Class-level setup
Test-level setup
Running uppercase test
Test-level teardown
Test-level setup
Running placeholder test
Test-level teardown
Class-level teardown

Ran 2 tests in 0.001s
OK

For controlling the execution order of tests, a TestSuite can be used. By default, unittest runs tests in alphabetical order based on method names. A TestSuite allows you to specify a custom sequence.

import unittest

class OrderedTestExample(unittest.TestCase):
    @classmethod
    def initialize_class(cls):
        print("Class setup")

    @classmethod
    def cleanup_class(cls):
        print("Class teardown")

    def initialize_test(self):
        print("Test setup")

    def cleanup_test(self):
        print("Test teardown")

    def test_second(self):
        print('Executing test_second')

    def test_first(self):
        print('Executing test_first')
        self.assertTrue('PYTHON'.isupper())

if __name__ == '__main__':
    test_collection = unittest.TestSuite()
    test_collection.addTest(OrderedTestExample("test_first"))
    test_collection.addTest(OrderedTestExample("test_second"))
    test_runner = unittest.TextTestRunner()
    test_runner.run(test_collection)

The class-level setUpClass and tearDownClass methods execute once for the entire test class, which is useful for expensive setup operations needed by multiple tests. In contrast, the instance-level setUp and tearDown methods run before and after each individual test method.

Beyond using unittest.main() directly, there are three primary methods for loading and executing tests.

Method 1: Using unittest.main() This is the simplest execution method, where the test runner discovers and runs all test methods within the module.

import unittest

class SimpleTestCase(unittest.TestCase):
    def setUp(self):
        # Pre-test initialization
        pass

    def tearDown(self):
        # Post-test cleanup
        pass

    def test_addition(self):
        # Test logic
        self.assertEqual(1 + 1, 2)

    def test_subtraction(self):
        # Test logic
        self.assertEqual(5 - 3, 2)

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

Method 2: Using a TestSuite This method provides explicit control over which tests are included and their execution order.

import unittest

class FunctionTest(unittest.TestCase):
    def setUp(self):
        # Pre-test initialization
        pass

    def tearDown(self):
        # Post-test cleanup
        pass

    def test_create_item(self):
        # Specific test script
        pass

    def test_remove_item(self):
        # Specific test script
        pass

if __name__ == '__main__':
    test_suite = unittest.TestSuite()
    test_suite.addTest(FunctionTest("test_create_item"))
    test_suite.addTest(FunctionTest("test_remove_item"))
    test_executor = unittest.TextTestRunner()
    test_executor.run(test_suite)

Method 3: Using TestLoader This approach is useful for loading tests from multiple classes or modules efficiently.

import unittest

class MathOperationsTest(unittest.TestCase):
    def test_sum(self):
        print('test_sum output')
        self.assertEqual(2+2, 4)

    def test_product(self):
        print('test_product output')
        self.assertEqual(3*3, 9)

class StringOperationsTest(unittest.TestCase):
    def test_concatenation(self):
        print('test_concatenation output')
        self.assertEqual('ab' + 'cd', 'abcd')

    def test_repetition(self):
        print('test_repetition output')
        self.assertEqual('a' * 3, 'aaa')

if __name__ == '__main__':
    loader = unittest.TestLoader()
    suite_a = loader.loadTestsFromTestCase(MathOperationsTest)
    suite_b = loader.loadTestsFromTestCase(StringOperationsTest)
    combined_suite = unittest.TestSuite([suite_a, suite_b])
    unittest.TextTestRunner(verbosity=2).run(combined_suite)

Tags: python Unit Testing unittest Test Automation Software Testing

Posted on Thu, 07 May 2026 15:35:39 +0000 by jaql