Werkboek — Hoofdstuk 11: Basis testen en debuggen
Let op: alle programmacode schrijf je in het Engels (zoals in het boek). De uitleg en opdrachten zijn in het Nederlands.
Doel van dit hoofdstuk
- Print‑debugging op een doelgerichte manier toepassen.
- Aannames vastleggen met
assert(ontwikkelchecks en in tests). - Kennismaken met
unittest(standaardbibliotheek) enpytest(populair framework). - Foutmeldingen (tracebacks) leren lezen en focussen op eigen code.
Richtlijnen
- Houd voorbeelden klein en gericht. Schrijf duidelijke functienamen in het Engels.
- Gebruik
assertin tests en als ontwikkelcheck; niet als gebruikersvalidatie in productiecode. - Voor
pytest: zorg dat bestands- en functienamen mettest_beginnen. - Als je met floats werkt: vergelijk met tolerantie (bijv.
abs(a-b) < 1e-9ofmath.isclose).
Oefening 1 — Print‑debugging (gericht kijken) Er is een functie met een bug:
# normalize_name.py
def normalize_name(s: str) -> str:
s = s.strip()
parts = s.split()
return "".join(part.lower() for part in parts) # BUG: mist spaties tussen woorden
- Schrijf een mini‑script dat de functie aanroept met
" Ada Lovelace ". - Voeg 2–3 doelgerichte debug‑prints toe (in het script of tijdelijk in de functie) om te zien wat er misgaat.
- Noteer (in comment) wat de bug is en hoe je die zou fixen.
Oefening 2 — Aannames met assert
Schrijf een functie average(values: list[float]) -> float die het gemiddelde teruggeeft.
- Voeg een
assert len(values) > 0, "values must not be empty"toe. - Demonstreer in een script het succespad en het falen (lege lijst) met de resulterende AssertionError.
Oefening 3 — Kleine assert‑tests zonder framework
Maak een bestand math_utils.py met functies add(a,b) en even_sum(n) (som van even getallen t/m n).
- Schrijf een tweede bestand
test_math_utils_sanity.pymet 4–6assert‑checks die deze functies controleren. - Run het testbestand gewoon met
pythonen laat mislukking/succes zien.
Oefening 4 — unittest basis
- Schrijf
test_math_utils_unittest.pymet eenunittest.TestCaseklasse met minstens twee testmethoden:test_add_basic()gebruiktself.assertEqual.test_even_sum_small()test enkele kleine gevallen.
- Laat zien hoe je dit runt met
python -m unittest -q(beschrijf de commandoregel in een comment).
Oefening 5 — pytest basis (installatie buiten scope hier)
- Schrijf
test_math_utils_pytest.pymet twee testfuncties vooraddeneven_sum. - Voeg een test toe die een exception verwacht met
pytest.raises(bijv. voor eendiv(a,b)die ZeroDivisionError gooit bijb==0). - Noteer in een comment hoe je dit zou draaien:
pytest -q.
Oefening 6 — Traceback lezen
Schrijf een klein script show_error.py dat bewust faalt (bijv. int("abc")).
- Plak (in comment) een voorbeeld‑traceback en markeer welke regel jouw code was en welk exceptietype werd gegooid.
- Schrijf 1–2 zinnen (NL) hoe je vanaf onder naar boven leest voor de kern.
Oefening 7 — Tolerantie bij floats
Schrijf circle_area(r) en schrijf daarvoor tests die niet exact op decimale weergave vertrouwen.
- Gebruik
abs(actual - expected) < 1e-9ofmath.isclosein je asserts. - Toon één case die zonder tolerantie flaky zou kunnen zijn.
Oefening 8 — Mini refactor met testnet
Schrijf def slugify(text: str) -> str (zoals in eerdere hoofdstukken) en schrijf 5 asserts die gewenste gedrag vastleggen (spaties → streepjes, lowercase, alleen alfanumeriek/streepjes).
- Introduceer bewust een bug (bijv.
joinzonder separator) en laat zien dat een assert faalt. - Fix de bug en laat alle asserts weer slagen.
Oefening 9 — unittest: exceptions en setup/teardown (licht)
- Maak in
math_utils.pyeendiv(a,b)die ZeroDivisionError gooit bijb==0. - Schrijf een
unittest.TestCasemetsetUpdie een paar veelgebruikte waarden opslaat. - Voeg een test toe met
assertRaises(ZeroDivisionError)voordiv(1,0).
Oefening 10 — Korte workflow & valkuilen
- Schrijf 3 bulletpoints (in comments) over jouw testworkflow (schrijf functie → bedenk voorbeelden → schrijf asserts → run → refactor → run).
- Noem 3 valkuilen en de remedies (bijv. alleen “happy path” testen, asserts met floats, assert in productie i.p.v. echte validatie).
Uitdaging (optioneel) — Kleine rekenmodule met volledige cyclus
Bouw calc2.py met functies add, sub, mul, div, pow en schrijf:
- Eenvoudige
pytest‑tests (of assert‑tests) die normale gevallen, randgevallen en exceptions afdekken. - Voeg 1–2
unittest‑tests toe als extra voorbeeld. - Laat zien hoe je
pytest -q/python -m unittestzou gebruiken (in comments).