Comprehensive Guide to Python unittest Framework
Initialization Methods
setUp and tearDown
These methods run before and after each test method. If you have multiple tests, setUp and tearDown execute multiple times, which can be resource-intensive.
setUpClass and tearDownClass
Recommended for one-time initialization of shared resources. These class methods run once per test class. Use the @classmethod decorator.
import unittest
class SearchEngineTest(unittest.TestCase):
@classmethod
def setUpClass(cls):
print("Initializing test class...")
@classmethod
def tearDownClass(cls):
print("Cleaning up test class...")
def test_search_engine_a(self):
print("Testing search engine A...")
def test_search_engine_b(self):
print("Testing search engine B...")
if __name__ == '__main__':
unittest.main(verbosity=1)
Verbosity Levels
unittest.main(verbosity=0/1/2) controls output detail:
- Default is 1 (shows test count and overall result)
- 0 provides minimal output
- 2 shows detailed information
Test Execution Order
Sequential Execution with addTest
Tests execute in the order they're added to the test suite.
import unittest
class SearchEngineTest(unittest.TestCase):
@classmethod
def setUpClass(cls):
print("Starting tests...")
@classmethod
def tearDownClass(cls):
print("Tests completed...")
def test_engine_a(self):
print("Testing engine A...")
def test_engine_b(self):
print("Testing engine B...")
if __name__ == '__main__':
test_suite = unittest.TestSuite()
test_suite.addTest(SearchEngineTest('test_engine_b'))
test_suite.addTest(SearchEngineTest('test_engine_a'))
unittest.TextTestRunner(verbosity=2).run(test_suite)
Running Specific Test Classes
Execute tests from a single class when you have multiple classes but only need one.
import unittest
class SearchEngineTestA(unittest.TestCase):
@classmethod
def setUpClass(cls):
print("Starting TestA...")
@classmethod
def tearDownClass(cls):
print("Completed TestA...")
def test_search_a(self):
print("Testing search A...")
class SearchEngineTestB(unittest.TestCase):
@classmethod
def setUpClass(cls):
print("Starting TestB...")
@classmethod
def tearDownClass(cls):
print("Completed TestB...")
def test_search_b(self):
print("Testing search B...")
if __name__ == '__main__':
# Method 1: Using makeSuite
test_suite = unittest.TestSuite(unittest.makeSuite(SearchEngineTestB))
# Method 2: Using TestLoader
# test_suite = unittest.TestLoader().loadTestsFromTestCase(SearchEngineTestB)
unittest.TextTestRunner(verbosity=2).run(test_suite)
Module-Level Test Execution
Run all tests in a module or directory for batch execution.
import unittest
import os
class SearchEngineTest(unittest.TestCase):
def test_search_engine(self):
print("Testing search engine...")
if __name__ == '__main__':
# Define test directory
current_dir = os.path.dirname(__file__)
print(f"Test directory: {current_dir}")
# Discover tests (supports regex patterns)
# discover = unittest.defaultTestLoader.discover(current_dir, pattern='test*.py')
discover = unittest.defaultTestLoader.discover(current_dir, pattern='search_test.py')
runner = unittest.TextTestRunner(verbosity=2).run(discover)
Shared Initialization Module
Separate common setup code into a base class for reuse.
import unittest
class BaseTestSetup(unittest.TestCase):
@classmethod
def setUpClass(cls):
print("Base setup: Initializing shared resources...")
@classmethod
def tearDownClass(cls):
print("Base teardown: Cleaning up shared resources...")
class SearchEngineTest(BaseTestSetup):
def test_search_functionality(self):
print("Testing search functionality...")
Test Skipping
Skip tests conditionally or unconditionally.
import unittest
class SearchEngineTest(unittest.TestCase):
def test_basic_search(self):
print("Running basic search test...")
@unittest.skip("Skipping this test case")
def test_advanced_search(self):
print("This test won't run...")
@unittest.skipIf(1 != 2, "Skipping when condition is false")
def test_conditional_search(self):
print("This test runs only when condition is true...")
if __name__ == '__main__':
unittest.main(verbosity=2)
Assertiosn
Common assertion methods for test validation.
def test_search_assertions(self):
# Equality assertions
self.assertEqual(5, 5) # Passes
self.assertNotEqual(5, 6) # Passes
# Boolean assertions
self.assertTrue(True) # Passes
self.assertFalse(False) # Passes
# Identity assertions
a = [1, 2, 3]
b = a
self.assertIs(a, b) # Passes (same object)
self.assertIsNot(a, [1, 2, 3]) # Passes (different objects)
# None assertions
self.assertIsNone(None) # Passes
self.assertIsNotNone(5) # Passes
# Membership assertions
self.assertIn(2, [1, 2, 3]) # Passes
self.assertNotIn(4, [1, 2, 3]) # Passes
Note: When an assertion fails, subsequent assertions in the same test method won't execute.