Skip to content

unittest.TestCase Methods

Common assertion methods provided by TestCase.

Equality and Comparison Assertions

Assert equality and inequality.

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.

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

"""
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)