Vermenigvuldigen controleren
Schrijf test_total. Controleer met assert dat pricing.total(4, 7) de afgesproken 28 geeft.
Gisteren klopte je prijsberekening; vandaag heeft iemand vermenigvuldigen door optellen vervangen. Je kunt opnieuw handmatig kijken, maar die controle vergeet je gemakkelijk bij de volgende wijziging. Een test bewaart een concrete afspraak als uitvoerbare code.
Een assertie is een controle die moet kloppen om verder te gaan. Met assert actual == expected vergelijk je de ontvangen waarde met de verwachte waarde. Als die vergelijking onwaar is, ontstaat een AssertionError.
Een geslaagde assertie print niets. Daarom roept het eerste voorbeeld de test echt aan en print het pas daarna een korte bevestiging. Alleen de functie definiëren voert haar inhoud nog niet uit.
def area(width, height):
return width * height
def test_area():
assert area(3, 4) == 12
test_area()
print("De oppervlakteafspraak klopt.")De oppervlakteafspraak klopt.
De naam test_area beschrijft de controle voor een mens. Python geeft een gewone functie met die naam nog geen bijzondere uitvoering. In de volgende les laat je een testbibliotheek zulke functies of methoden organiseren.
Kies eerst invoer waarvan je de betekenis begrijpt. Bepaal daarna de verwachte uitkomst vanuit de afspraak. Roep tenslotte de echte functie aan en vergelijk beide waarden.
Bij een rechthoek van drie bij vier is de afspraak twaalf vierkante eenheden. De verwachting staat vast vóór je de berekening uitvoert. Je wilt niet eerst het antwoord van de functie bekijken en datzelfde antwoord vervolgens goedkeuren.
Gebruik kleine getallen die je zelf kunt narekenen. Als een test mislukt, wil je kunnen uitleggen welke afspraak is geschonden. Een lange willekeurige lijst is daarvoor niet automatisch beter dan één zorgvuldig gekozen geval.
Een tegenvoorbeeld is een geval dat laat zien dat een bewering niet altijd klopt. De foutieve oppervlaktefunctie hieronder telt twee zijden op. Met drie en vier levert dat zeven, zodat dezelfde controle de fout ontdekt.
def area(width, height):
return width + height
def test_area():
assert area(3, 4) == 12, "drie bij vier moet twaalf zijn"
try:
test_area()
except AssertionError as error:
print(type(error).__name__ + ": " + str(error))AssertionError: drie bij vier moet twaalf zijn
Dit voorbeeld vangt de assertiefout alleen op om de ontdekking zichtbaar af te drukken. In je eigen test laat je zo'n mislukte assertie doorlopen. Anders lijkt een gebroken afspraak alsnog geslaagd.
Eén groen geval bewijst niet dat een functie overal goed werkt. Twee en twee zijn bijvoorbeeld onhandige afmetingen om optellen van vermenigvuldigen te onderscheiden: beide leveren vier. Denk daarom ook na over een gewone fout die jouw geval werkelijk zou ontmaskeren.
assert result == result blijft waar, ook als result verkeerd is. Dezelfde foutieve berekening aan beide kanten herhalen helpt evenmin. Een test heeft een onafhankelijke verwachting nodig.
Gebruik assert voor deze ontwikkelcontroles, niet als blijvende invoerbeveiliging van je programma. Python kan asserties bij geoptimaliseerde uitvoering weglaten. Voor invoerfouten blijven de expliciete controles met raise uit module6 geschikt.
De meegeleverde module pricing berekent het totaal als aantal maal prijs per stuk. Beide argumenten zijn hier niet-negatieve gehele getallen; een aantal of prijs van nul geeft dus nul. Je schrijft alleen tests in test_pricing.py en verandert de bibliotheek niet.
Elke test moet de echte pricing.total aanroepen en de uitkomst controleren. We voeren dezelfde test ook tegen gewone verkeerde berekeningen uit. Zo merk je of je controle werkelijk iets ontdekt.
Schrijf test_total. Controleer met assert dat pricing.total(4, 7) de afgesproken 28 geeft.
Schrijf test_zero_count. Controleer dat pricing.total(0, 7) nul geeft, zodat een fout die minstens één artikel rekent zichtbaar wordt.
Schrijf test_zero_price. Controleer dat pricing.total(3, 0) nul geeft en ontdek daarmee een fout die prijs nul door één vervangt.
Schrijf test_other_totals. Controleer zowel pricing.total(1, 4) als pricing.total(2, 6) met hun eigen verwachte uitkomst.
Hierna gebruik je unittest om meerdere controles samen uit te voeren en hun resultaten te verzamelen.
Voer je code uit en ontdek
wat je hebt gemaakt.
Je hoeft het niet in één keer goed te doen. Na het uitvoeren zie je hier welke stappen al kloppen.