unittest

Updated March 13, 2026 · Modules
testing unit-testing assertions testcase testrunner

The unittest module is Python’s built-in unit testing framework. It was inspired by JUnit and provides test automation, fixture management, and test organization through an object-oriented approach. Whether you’re writing simple assertions or complex test suites, unittest gives you the tools to verify your code works correctly.

TestCase Class

The TestCase class is the foundation of unittest. You create test cases by subclassing it and implementing methods that start with test:

import unittest

class TestMathOperations(unittest.TestCase):
    def test_addition(self):
        result = 2 + 3
        self.assertEqual(result, 5)

Key Methods

MethodDescription
setUp()Runs before each test method. Use it to prepare test fixtures.
tearDown()Runs after each test method. Use it for cleanup.
setUpClass()Runs once before all tests in the class. Must be a classmethod.
tearDownClass()Runs once after all tests in the class. Must be a classmethod.
import unittest

class Widget:
    def __init__(self, name):
        self.name = name
    def size(self):
        return (50, 50)

class WidgetTestCase(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        print("Setting up WidgetTestCase")
    
    def setUp(self):
        self.widget = Widget("test")
    
    def test_default_size(self):
        self.assertEqual(self.widget.size(), (50, 50))
    
    def tearDown(self):
        # cleanup if needed
        pass

Assertion Methods

TestCase provides many assertion methods. These are the most commonly used:

assertEqual(first, second, msg=None)

Checks that two values are equal. This is the most frequently used assertion.

def test_equality(self):
    self.assertEqual(2 + 2, 4)
    self.assertEqual("hello".upper(), "HELLO")
    self.assertEqual([1, 2, 3], [1, 2, 3])

Parameters:

ParameterTypeDefaultDescription
firstanyThe first value to compare
secondanyThe second value to compare
msgstrNoneOptional message displayed on failure

assertTrue(expr, msg=None)

Checks that an expression is truthy.

def test_truthy(self):
    self.assertTrue(1 == 1)
    self.assertTrue("non-empty")
    self.assertTrue([1, 2])  # non-empty list is truthy

assertFalse(expr, msg=None)

Checks that an expression is falsy.

def test_falsy(self):
    self.assertFalse(1 == 2)
    self.assertFalse("")
    self.assertFalse(None)

assertIsNone(obj, msg=None)

Checks that an object is None.

def test_none(self):
    result = some_function()
    self.assertIsNone(result)

assertRaises(expected_exception, callable, *args, **kwargs)

Checks that a callable raises a specific exception. Use it with a context manager for more control:

def test_raises(self):
    with self.assertRaises(ValueError):
        int("not a number")
    
    with self.assertRaises(ZeroDivisionError):
        x = 1 / 0

Parameters:

ParameterTypeDefaultDescription
expected_exceptionExceptionThe exception type expected
callablecallableThe function to call
*argsanyPositional arguments for callable
**kwargsanyKeyword arguments for callable

TestSuite and TestRunner

A TestSuite groups multiple tests together. A TestRunner executes the tests and reports results.

import unittest

# Create a test suite
loader = unittest.TestLoader()
suite = unittest.TestSuite()

# Load tests from a TestCase
suite.addTests(loader.loadTestsFromTestCase(WidgetTestCase))

# Or load from a module
suite.addTests(loader.loadTestsFromName('myapp.tests'))

# Run the tests
runner = unittest.TextTestRunner(verbosity=2)
result = runner.run(suite)

TextTestRunner

The default test runner. It outputs results to the console.

runner = unittest.TextTestRunner(verbosity=1)
result = runner.run(suite)

# Check results
print(f"Tests run: {result.testsRun}")
print(f"Failures: {len(result.failures)}")
print(f"Errors: {len(result.errors)}")

unittest.main()

The simplest way to run tests. It discovers all test methods in the current module and executes them:

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

From the command line:

python -m unittest
python -m unittest -v                 # verbose
python -m unittest -v mymodule       # specific module
python -m unittest MyTest.test_one   # specific test method
python -m unittest discover          # discover all tests

Command-line options

OptionDescription
-vVerbose output
-bBuffer stdout/stderr during tests
-fStop on first failure
-k patternRun tests matching pattern

unittest.mock Submodule

For mocking, use unittest.mock. It lets you replace real objects with fake ones during testing:

from unittest.mock import Mock, patch, MagicMock

# Create a mock
mock_obj = Mock()
mock_obj.method.return_value = 42
result = mock_obj.method()
assert result == 42
mock_obj.method.assert_called_once()

# Patch a function
@patch('mymodule.some_function')
def test_something(mock_fn):
    mock_fn.return_value = 'mocked'
    # ...

# MagicMock automatically handles magic methods
mock_list = MagicMock()
mock_list.__getitem__.return_value = 'mocked item'
print(mock_list[0])  # mocked item

Common mock utilities:

ClassDescription
MockA flexible mock object that creates attributes on access
MagicMockMock with magic method support (for __str__, __len__, etc.)
patch()Decorator/context manager to replace objects temporarily
sentinelCreates unique sentinel objects for testing

Skipping Tests

Sometimes you need to skip a test temporarily:

class MyTests(unittest.TestCase):
    @unittest.skip("reason for skipping")
    def test_skipped(self):
        self.fail("this won't run")
    
    @unittest.skipIf(condition, "reason")
    def test_conditionally_skipped(self):
        pass
    
    @unittest.skipUnless(condition, "reason")
    def test_only_on_condition(self):
        pass

See Also