Een gevonden testmethode
Maak RemainingTests als subklasse van unittest.TestCase en schrijf test_available. Controleer met self.assertEqual dat quota.remaining(10, 3) zeven geeft.
Je eerste test ontdekt een fout, maar je programma heeft inmiddels meer afspraken. Als je iedere functie handmatig onderaan het bestand aanroept, vergeet je gemakkelijk een nieuwe controle. Je wilt dat één uitvoerder alle bedoelde tests vindt en hun resultaten bij elkaar houdt.
unittest is de testbibliotheek die met Python wordt meegeleverd. Een klasse die erft van unittest.TestCase verzamelt je controles als methoden. Je kent klassen en overerving al; hier gebruik je een bestaande basis met hulpmethoden.
Een testmethode begint in deze les met test_ en krijgt self. Met self.assertEqual(actual, expected) vergelijk je de ontvangen waarde met de verwachte waarde. Je schrijft een vergelijking, geen opdracht om het antwoord te veranderen.
Het eerste voorbeeld test een labelmaker. De gewone invoer en de lege invoer hebben ieder een eigen methode, zodat je later afzonderlijk ziet welke afspraak is gebroken.
import unittest
def label(text):
return text.strip().upper()
class LabelTests(unittest.TestCase):
def test_regular_label(self):
self.assertEqual(label(" fiets "), "FIETS")
def test_empty_label(self):
self.assertEqual(label(" "), "")
suite = unittest.defaultTestLoader.loadTestsFromTestCase(LabelTests)
result = unittest.TestResult()
suite.run(result)
print("Uitgevoerd:", result.testsRun)
print("Mislukte controles:", len(result.failures))
print("Uitvoerfouten:", len(result.errors))Uitgevoerd: 2 Mislukte controles: 0 Uitvoerfouten: 0
Een testloader zoekt de testmethoden en maakt daar uitvoerbare tests van. loadTestsFromTestCase krijgt de klasse, niet een zelfgekozen antwoord of een lijst succesmeldingen. De suite die terugkomt groepeert de gevonden controles.
Daarna voert suite.run(result) die controles echt uit. Het resultaat telt hoeveel tests draaiden en verzamelt wat misging. Het voorbeeld print die gemeten aantallen; het zegt niet vooraf dat alles gelukt is.
Een verzameling in een lijst zetten voert haar tests nog niet uit. Dat lijkt op het verschil tussen een functie bewaren en haar aanroepen. Houd laden en draaien daarom als twee herkenbare stappen in je hoofd.
Een naam zoals test_empty_label vertelt sneller wat misging dan test_second. Kies één hoofdreden waarom een methode zou falen. Twee sterk verschillende afspraken passen vaak beter in twee methoden.
Een failure betekent dat een controle niet aan haar verwachting voldeed. Een error betekent dat de test door een andere onverwachte fout niet normaal kon worden afgerond, bijvoorbeeld doordat een naam ontbreekt. Beide vragen aandacht, maar ze wijzen je naar een ander begin van het onderzoek.
Verander bij een rood resultaat niet meteen de verwachting. Reken eerst de afspraak na en bekijk de ontvangen waarde. Anders kun je een fout in het programma per ongeluk tot de nieuwe norm maken.
Een methode check_label wordt met de standaardnaamgeving niet als test gevonden. Het tweede voorbeeld bevat precies die fout. Er mislukt niets, omdat er ook niets wordt uitgevoerd.
import unittest
class HiddenTests(unittest.TestCase):
def check_label(self):
self.assertEqual("fiets".upper(), "VERKEERD")
suite = unittest.defaultTestLoader.loadTestsFromTestCase(HiddenTests)
result = unittest.TestResult()
suite.run(result)
print("Uitgevoerd:", result.testsRun)
print("Geslaagd volgens het lege resultaat:", result.wasSuccessful())Uitgevoerd: 0 Geslaagd volgens het lege resultaat: True
Controleer daarom naast de uitkomst ook dat het bedoelde aantal tests draaide. Een leeg rapport bewijst niets over de labelmaker. De lescontrole accepteert evenmin een overgeslagen test als bewijs voor een afspraak.
De meegeleverde functie quota.remaining(limit, used) berekent het resterende aantal plaatsen. Zij geeft het verschil terug zolang er ruimte is en nul wanneer de grens bereikt of overschreden is. De argumenten zijn hier niet-negatieve gehele getallen.
Schrijf de gevraagde methoden in RemainingTests. Elke methode roept de echte functie aan en vergelijkt haar antwoord met de afgesproken waarde. De bibliotheek blijft meegeleverd, zodat jij je op de teststructuur kunt richten.
Maak RemainingTests als subklasse van unittest.TestCase en schrijf test_available. Controleer met self.assertEqual dat quota.remaining(10, 3) zeven geeft.
Schrijf de methode test_exact_limit. Controleer dat quota.remaining(10, 10) nul geeft.
Schrijf test_over_limit. Controleer dat quota.remaining(10, 13) nul geeft en ontdek een berekening die min drie laat staan.
Schrijf test_other_limits. Controleer in dezelfde methode zowel quota.remaining(5, 1) als quota.remaining(20, 2) met hun eigen verwachte waarde.
Hierna schrijf je dezelfde soort afspraken als compacte pytest-functies.
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.