Skip to content

unittest.TestCase Methods

Common assertion methods provided by TestCase.

Mental Model

TestCase assertion methods are specialized comparisons that produce clear failure messages. assertEqual(a, b) is not just assert a == b — it tells you what a and b actually were when they differed. Choosing the most specific assertion (e.g., assertIn, assertRaises, assertAlmostEqual) gives you the most informative error output when a test fails.

Equality and Comparison Assertions

Assert equality and inequality.

```python import unittest

class TestAssertions(unittest.TestCase): def test_equal(self): self.assertEqual(5, 5)

def test_not_equal(self):
    self.assertNotEqual(5, 3)

def test_greater(self):
    self.assertGreater(10, 5)

def test_less(self):
    self.assertLess(3, 5)

def test_almost_equal(self):
    self.assertAlmostEqual(0.1 + 0.2, 0.3, places=2)

if name == 'main': unittest.main(argv=[''], exit=False, verbosity=2) ```

test_almost_equal ... ok test_equal ... ok test_greater ... ok test_less ... ok test_not_equal ... ok

Container and Type Assertions

Assert membership, containment, and types.

```python import unittest

class TestContainers(unittest.TestCase): def test_in(self): self.assertIn(2, [1, 2, 3])

def test_not_in(self):
    self.assertNotIn(4, [1, 2, 3])

def test_is_instance(self):
    self.assertIsInstance("hello", str)

def test_is_none(self):
    self.assertIsNone(None)

def test_is_not_none(self):
    self.assertIsNotNone(42)

def test_true(self):
    self.assertTrue(5 > 3)

def test_false(self):
    self.assertFalse(5 < 3)

if name == 'main': unittest.main(argv=[''], exit=False, verbosity=2) ```

test_false ... ok test_in ... ok test_is_instance ... ok test_is_none ... ok test_is_not_none ... ok test_true ... ok


Runnable Example: search_sort_test_example.py

```python """ Unit Testing: Testing Search and Sort Algorithms

Practical unittest example that tests real algorithms (search and sort) with setUp/tearDown, multiple assertion methods, and edge cases.

Topics covered: - unittest.TestCase subclassing - setUp() for test data preparation - Test method naming (test_ prefix) - Assertion methods (assertEqual, assertLessEqual, assertRaises) - Running tests: python -m unittest or pytest

Based on concepts from Python-100-Days test files and ch07/testing materials. """

import unittest

=============================================================================

Functions Under Test

=============================================================================

def sequential_search(items: list, target) -> int: """Linear search - returns index or -1.""" for i, item in enumerate(items): if item == target: return i return -1

def binary_search(items: list, target) -> int: """Binary search on sorted list - returns index or -1.""" start, end = 0, len(items) - 1 while start <= end: mid = (start + end) // 2 if target > items[mid]: start = mid + 1 elif target < items[mid]: end = mid - 1 else: return mid return -1

def selection_sort(items: list) -> list: """Selection sort - returns new sorted list.""" result = items[:] for i in range(len(result) - 1): min_idx = i for j in range(i + 1, len(result)): if result[j] < result[min_idx]: min_idx = j result[i], result[min_idx] = result[min_idx], result[i] return result

def merge(left: list, right: list) -> list: """Merge two sorted lists into one sorted list.""" result = [] i, j = 0, 0 while i < len(left) and j < len(right): if left[i] <= right[j]: result.append(left[i]) i += 1 else: result.append(right[j]) j += 1 result.extend(left[i:]) result.extend(right[j:]) return result

=============================================================================

Test Case 1: Search Algorithm Tests

=============================================================================

class TestSearchAlgorithms(unittest.TestCase): """Tests for sequential and binary search."""

def setUp(self):
    """Prepare test data - runs before EACH test method."""
    self.unsorted = [35, 97, 12, 68, 55, 73, 81, 40]
    self.sorted = [12, 35, 40, 55, 68, 73, 81, 97]

def test_sequential_search_found(self):
    """Test sequential search finds existing elements."""
    self.assertEqual(0, sequential_search(self.unsorted, 35))
    self.assertEqual(2, sequential_search(self.unsorted, 12))
    self.assertEqual(6, sequential_search(self.unsorted, 81))
    self.assertEqual(7, sequential_search(self.unsorted, 40))

def test_sequential_search_not_found(self):
    """Test sequential search returns -1 for missing elements."""
    self.assertEqual(-1, sequential_search(self.unsorted, 99))
    self.assertEqual(-1, sequential_search(self.unsorted, 7))

def test_sequential_search_empty_list(self):
    """Test sequential search on empty list."""
    self.assertEqual(-1, sequential_search([], 42))

def test_binary_search_found(self):
    """Test binary search finds elements in sorted list."""
    self.assertEqual(1, binary_search(self.sorted, 35))
    self.assertEqual(0, binary_search(self.sorted, 12))
    self.assertEqual(6, binary_search(self.sorted, 81))
    self.assertEqual(2, binary_search(self.sorted, 40))
    self.assertEqual(7, binary_search(self.sorted, 97))

def test_binary_search_not_found(self):
    """Test binary search returns -1 for missing elements."""
    self.assertEqual(-1, binary_search(self.sorted, 7))
    self.assertEqual(-1, binary_search(self.sorted, 99))

def test_binary_search_single_element(self):
    """Test binary search with single-element list."""
    self.assertEqual(0, binary_search([42], 42))
    self.assertEqual(-1, binary_search([42], 99))

=============================================================================

Test Case 2: Sort Algorithm Tests

=============================================================================

class TestSortAlgorithms(unittest.TestCase): """Tests for sorting algorithms."""

def setUp(self):
    self.data = [35, 97, 12, 68, 55, 73, 81, 40]
    self.expected = [12, 35, 40, 55, 68, 73, 81, 97]

def test_selection_sort_correctness(self):
    """Test that selection sort produces correct order."""
    result = selection_sort(self.data)
    self.assertEqual(result, self.expected)

def test_selection_sort_no_side_effects(self):
    """Test that original list is not modified."""
    original = self.data[:]
    selection_sort(self.data)
    self.assertEqual(self.data, original)

def test_selection_sort_already_sorted(self):
    """Test sorting an already sorted list."""
    result = selection_sort(self.expected)
    self.assertEqual(result, self.expected)

def test_selection_sort_reverse_sorted(self):
    """Test sorting a reverse-sorted list."""
    result = selection_sort([5, 4, 3, 2, 1])
    self.assertEqual(result, [1, 2, 3, 4, 5])

def test_selection_sort_duplicates(self):
    """Test sorting with duplicate values."""
    result = selection_sort([3, 1, 4, 1, 5, 9, 2, 6, 5])
    for i in range(len(result) - 1):
        self.assertLessEqual(result[i], result[i + 1])

def test_selection_sort_empty(self):
    """Test sorting empty list."""
    self.assertEqual(selection_sort([]), [])

def test_selection_sort_single_element(self):
    """Test sorting single-element list."""
    self.assertEqual(selection_sort([42]), [42])

=============================================================================

Test Case 3: Merge Function Tests

=============================================================================

class TestMerge(unittest.TestCase): """Tests for the merge helper function."""

def test_merge_basic(self):
    """Test merging two sorted lists."""
    left = [12, 35, 68, 97]
    right = [40, 55, 73, 81]
    result = merge(left, right)
    for i in range(len(result) - 1):
        self.assertLessEqual(result[i], result[i + 1])

def test_merge_preserves_length(self):
    """Test that merge output has correct length."""
    left = [1, 3, 5]
    right = [2, 4, 6]
    result = merge(left, right)
    self.assertEqual(len(result), len(left) + len(right))

def test_merge_empty_left(self):
    """Test merging with empty left list."""
    self.assertEqual(merge([], [1, 2, 3]), [1, 2, 3])

def test_merge_empty_right(self):
    """Test merging with empty right list."""
    self.assertEqual(merge([1, 2, 3], []), [1, 2, 3])

def test_merge_both_empty(self):
    """Test merging two empty lists."""
    self.assertEqual(merge([], []), [])

if name == 'main': unittest.main(verbosity=2) ```


Exercises

Exercise 1. Write a TestCase that tests a clamp(value, lo, hi) function using assertEqual, assertGreaterEqual, and assertLessEqual. The function should return lo if value < lo, hi if value > hi, and value otherwise.

Solution to Exercise 1

```python import unittest

def clamp(value, lo, hi): if value < lo: return lo if value > hi: return hi return value

class TestClamp(unittest.TestCase): def test_within_range(self): self.assertEqual(clamp(5, 0, 10), 5)

def test_below_range(self):
    result = clamp(-5, 0, 10)
    self.assertEqual(result, 0)
    self.assertGreaterEqual(result, 0)

def test_above_range(self):
    result = clamp(15, 0, 10)
    self.assertEqual(result, 10)
    self.assertLessEqual(result, 10)

if name == "main": unittest.main() ```


Exercise 2. Use assertAlmostEqual to test that math.sin(math.pi) is approximately zero. Why would assertEqual fail here?

Solution to Exercise 2

```python import unittest import math

class TestSin(unittest.TestCase): def test_sin_pi(self): self.assertAlmostEqual(math.sin(math.pi), 0, places=10)

if name == "main": unittest.main() ```

assertEqual would fail because math.sin(math.pi) returns a tiny floating-point number like 1.2246e-16 due to floating-point precision, not exactly 0. assertAlmostEqual checks within a tolerance.


Exercise 3. Write tests for a Stack class using assertRaises for popping from an empty stack, assertIn for checking membership after push, and assertIsNone for checking the return value of push.

Solution to Exercise 3

```python import unittest

class Stack: def init(self): self._items = [] def push(self, item): self._items.append(item) def pop(self): if not self._items: raise IndexError("Pop from empty stack") return self._items.pop() def contains(self, item): return item in self._items

class TestStack(unittest.TestCase): def test_pop_empty(self): s = Stack() with self.assertRaises(IndexError): s.pop()

def test_push_contains(self):
    s = Stack()
    s.push(42)
    self.assertIn(42, s)

def test_push_returns_none(self):
    s = Stack()
    result = s.push(1)
    self.assertIsNone(result)

if name == "main": unittest.main() ```


Exercise 4. Use assertCountEqual to verify that a function unique_chars(s) returns the correct set of characters regardless of order.

Solution to Exercise 4

```python import unittest

def unique_chars(s): return list(set(s))

class TestUniqueChars(unittest.TestCase): def test_unique(self): result = unique_chars("banana") self.assertCountEqual(result, ["b", "a", "n"])

def test_empty(self):
    self.assertCountEqual(unique_chars(""), [])

if name == "main": unittest.main() ```