05 / BUILDING USEFUL TOOLS · LESSON 20

Test the contract

Write unit tests that catch boundary and always-true mistakes.

17 min · learn at your pace

Make expectations executable

Python includes unittest in its standard library. A class inheriting from unittest.TestCase groups tests, and methods beginning with test_ are discovered automatically. Assertions such as assertEqual, assertTrue, and assertRaises explain what must happen.

A passing test proves only the case it checked. For a threshold rule, cover a value below the threshold, exactly on it, and above it. Include a custom threshold to catch a function that accidentally hard-codes the default.

Check that the tests can fail

This lesson also tries deliberately broken versions of your function: one always returns true, and another treats the boundary as low memory. Your tests must detect both. This is a small example of mutation testing, where a known mistake measures whether the tests notice a change in behaviour.

Use the shown loader and runner to display your own test results. A guarded runner avoids executing them during import. unittest.main() normally exits the interpreter; the explicit runner is easier to reuse in this persistent browser session. The lab’s Check button runs separate course checks in a fresh worker and reports their results independently of terminal text.

Try an example.py
import unittest

def is_low_memory(memory_gb, minimum_gb=16):
    return memory_gb < minimum_gb

class TestMemory(unittest.TestCase):
    def test_below(self):
        self.assertTrue(is_low_memory(8))
    def test_boundary(self):
        self.assertFalse(is_low_memory(16))
    def test_above(self):
        self.assertFalse(is_low_memory(32))
    def test_custom_threshold(self):
        self.assertTrue(is_low_memory(20, minimum_gb=24))

if __name__ == "__main__":
    suite = unittest.defaultTestLoader.loadTestsFromTestCase(TestMemory)
    unittest.TextTestRunner(verbosity=2).run(suite)
YOUR TURN

Put it into practice.

Implement is_low_memory(memory_gb, minimum_gb=16), returning True only below the threshold. Add a TestMemory unittest.TestCase with at least three non-skipped tests. Cover below, equal, above, and a custom threshold. Your tests must reject both an always-True function and a <= boundary bug. Keep the runner behind a main guard.

See an explained solution
One way to solve it.py
import unittest

def is_low_memory(memory_gb, minimum_gb=16):
    return memory_gb < minimum_gb

class TestMemory(unittest.TestCase):
    def test_below(self):
        self.assertTrue(is_low_memory(8))
    def test_boundary(self):
        self.assertFalse(is_low_memory(16))
    def test_above(self):
        self.assertFalse(is_low_memory(32))
    def test_custom_threshold(self):
        self.assertTrue(is_low_memory(20, minimum_gb=24))

if __name__ == "__main__":
    suite = unittest.defaultTestLoader.loadTestsFromTestCase(TestMemory)
    unittest.TextTestRunner(verbosity=2).run(suite)

The test class covers both sides of the boundary and a policy override. It can be imported without running; the guarded explicit runner displays results when you choose Run.