A test is code that checks your other code. Instead of running your program and eyeballing the output, you write tests that automatically prove it works โ and keep proving it as you make changes.
Tests are a safety net. When you add a feature and a test suddenly fails, you've caught a bug before your users do.
โ The assert statement
The simplest test tool: assert checks that something is true. If it isn't, your program stops and tells you.
Test-first! Write three asserts for a function you have not written yet โ is_even(4) is True, is_even(7) is False, is_even(0) is True (Red). Then write is_even with the % operator until they all pass (Green) and print Tests passed!.
Write safe_average(nums) that returns the average of a list โ but returns 0 for an empty list (the tricky edge case that crashes careless code). Assert it for [2, 4], [5] and [], then print All edge cases passed!.
Professional code is code you can change without fear โ and that fear disappears only when tests have your back. Write lots of them.
โ
Task 4: Your First Assertions
Easy
assert says "this must be true, or stop everything". Write double(n), then assert it works for 2, 0 and โ3, and print All tests passed โ at the end. If an assert fails you will see the error instead.
Bugs hide at the edges. Write grade(score) returning "A" for 90+, "B" for 80+, otherwise "F", then assert the exact boundaries: 90, 89, 80, 79 and 100. Print Edges are safe ๐ก๏ธ.
Edges are safe ๐ก๏ธ
def grade(score):
if score >= 90:
return "A"
if score >= 80:
return "B"
return "F"
assert grade(100) == "A"
assert grade(90) == "A"
assert grade(89) == "B"
assert grade(80) == "B"
assert grade(79) == "F"
print("Edges are safe ๐ก๏ธ")
๐
Task 6: Find the Bug With a Test
Medium
This function is wrong: def biggest(items): return items[0]. First write a test that proves it (assert biggest([3, 9, 2]) == 9 will fail), then fix the function so the test passes. Print Bug squashed ๐.
Bug squashed ๐
def biggest(items):
best = items[0]
for item in items:
if item > best:
best = item
return best
assert biggest([3, 9, 2]) == 9
assert biggest([5]) == 5
assert biggest([-4, -1]) == -1
print("Bug squashed ๐")
๐ด
Task 7: TDD: Red, Green, Refactor
Tricky
Write the tests first for a function initials(full_name) that turns "ada lovelace" into "A.L.". Write three asserts, watch them fail, then write the function until they pass. Print Green! ๐ข.
Green! ๐ข
def initials(full_name):
return "".join(part[0].upper() + "." for part in full_name.split())
assert initials("ada lovelace") == "A.L."
assert initials("grace brewster hopper") == "G.B.H."
assert initials("plato") == "P."
print("Green! ๐ข")
๐ฅ
Task 8: Test That It Fails Properly
Tricky
Good code refuses bad input. Write square_root(n) that raises ValueError for negatives, then test it with try/except: assert the normal case, and confirm the error is raised for โ9. Print Errors handled ๐ฅ.
Errors handled ๐ฅ
def square_root(n):
if n < 0:
raise ValueError("no square root of a negative number")
return n ** 0.5
assert square_root(9) == 3.0
try:
square_root(-9)
raised = False
except ValueError:
raised = True
assert raised
print("Errors handled ๐ฅ")
๐งซ
Task 9: Boss Level: Test a Whole Class
Boss
Write a ShoppingCart class with add(item, price), total() and remove(item), then write at least six assertions covering an empty cart, one item, several items, removing an item, and removing something that is not there (it should not crash). Print Cart is solid ๐.