Learning Goals
3 min- Pick the right assertion: equal, true/false, in, is, almost-equal.
- Assert exceptions and their messages with
assertRaises. - Use container assertions (
assertIn,assertCountEqual). - Know why a specific assertion beats
assertTrue(a == b).
Warm-Up · The Right Tool
5 min# both check the same thing — but the failure messages differ wildly: self.assertTrue(result == 120) # fails with: "False is not true" 😞 self.assertEqual(result, 120) # fails with: "119 != 120" 😀
Always use the most specific assertion for the job. assertEqual shows both values; assertIn shows the item and the container; assertRaises shows what was expected. Specific assertions = readable failures = fast debugging.
New Concept · The Dozen You Need
14 minEquality & identity
self.assertEqual(a, b) # a == b self.assertNotEqual(a, b) # a != b self.assertIs(a, b) # a is b (same object) self.assertIsNone(x) # x is None self.assertIsNotNone(x) # x is not None
Truthiness
self.assertTrue(x) # bool(x) is True self.assertFalse(x) # bool(x) is False
Membership & type
self.assertIn("a", ["a", "b"]) # item in container self.assertNotIn("z", ["a", "b"]) self.assertIsInstance(x, int) # type check
Numbers — floats need almostEqual
self.assertAlmostEqual(0.1 + 0.2, 0.3) # within 7 decimal places self.assertGreater(score, 0) self.assertLessEqual(age, 120)
Exceptions
# just that it raises: with self.assertRaises(ValueError): withdraw(50, 100) # also check the message: with self.assertRaises(ValueError) as cm: withdraw(50, 100) self.assertIn("insufficient", str(cm.exception))
Collections
self.assertCountEqual([3, 1, 2], [1, 2, 3]) # same items, any order self.assertListEqual([1, 2], [1, 2]) # same items, same order
The cheat sheet
checking... use... two values equal assertEqual a float result assertAlmostEqual True / False assertTrue / assertFalse None assertIsNone / assertIsNotNone item in a list/dict assertIn an exception is raised assertRaises same items, any order assertCountEqual
Worked Example · A Rich Test Suite
12 min# test_inventory.py — using the right assertion each time import unittest from inventory import Inventory class TestInventory(unittest.TestCase): def setUp(self): self.inv = Inventory() def test_starts_empty(self): self.assertEqual(len(self.inv), 0) self.assertIsNone(self.inv.find("sword")) def test_add_item(self): self.inv.add("sword", 3) self.assertIn("sword", self.inv.names()) self.assertEqual(self.inv.count("sword"), 3) def test_total_value_is_float(self): self.inv.add("gem", 2, price=9.99) self.assertAlmostEqual(self.inv.total_value(), 19.98) def test_remove_too_many_raises(self): self.inv.add("potion", 1) with self.assertRaises(ValueError) as cm: self.inv.remove("potion", 5) self.assertIn("only 1", str(cm.exception)) def test_names_unordered(self): self.inv.add("a", 1); self.inv.add("b", 1) self.assertCountEqual(self.inv.names(), ["b", "a"]) if __name__ == "__main__": unittest.main()
Read the diff
Each test reaches for the most precise assertion: assertIsNone for the empty lookup, assertAlmostEqual for the money total, assertRaises + message check for the error, assertCountEqual because name order doesn't matter. When any fails, the message tells you the exact mismatch — no guessing. (We'll meet that setUp method properly next lesson.)
Try It Yourself
13 minFor each check, name the best assertion: "result is 42", "list contains 'x'", "value is None", "0.3 within rounding", "raises KeyError".
Answer
assertEqual, assertIn, assertIsNone, assertAlmostEqual, assertRaises(KeyError).
Write a test that asserts both that a function raises ValueError AND that the message contains a specific word, using the as cm pattern.
Test a function that returns a list whose order isn't guaranteed (e.g., dict keys). Use assertCountEqual so the test doesn't flake on ordering.
Mini-Challenge · Assertion Coverage
8 minWrite a single TestCase that uses at least eight different assertion methods on a small class of your choice. Each test method should pick the most precise assertion for its check.
Recap
3 minUse the most specific assertion: assertEqual for values, assertAlmostEqual for floats, assertIn for membership, assertIsNone for None, assertRaises (+ message check) for exceptions, assertCountEqual for order-independent collections. Specific assertions produce readable failures, which is the whole game. Next: lifecycle hooks with setUp/tearDown.
Vocabulary Card
- assertAlmostEqual
- Float-safe equality within a tolerance (default 7 decimals).
- assertIn
- Asserts an item is in a container; reports both on failure.
- assertRaises (as cm)
- Captures the exception so you can also assert its message.
- assertCountEqual
- Same elements regardless of order — avoids flaky ordering tests.
Homework
4 minRefactor a previous test suite to use the most precise assertion in every test (no bare assertTrue(a == b)). Add at least one assertAlmostEqual, one assertRaises with a message check, and one assertCountEqual. Run with -v.
Use test_inventory.py as the model — it demonstrates seven different assertion types in one suite.