← Python/Eindproject: Urenrapport
Les 8 van 8
MODULE 14 · 08◷ 35 min

De hele opdracht met echte regressietests bewaken

Na deze les kun je
  • Een volledige CLI-opdracht met echte bestanden testen.
  • Verwachte waarden onafhankelijk van de productcode vastleggen.
  • Bewijzen dat tests relevante regressies ook werkelijk herkennen.

Alle onderdelen van het urenrapport hebben hun eigen afspraken. Toch kan een wijziging in de verbinding ertussen het eindresultaat veranderen. In deze laatste les schrijf je regressietests die een echte bron via de CLI tot een echt uitvoerbestand laten lopen.

Het geheel heeft een eigen contract

Een losse parsertest bewijst niet dat de CLI de gekozen datums doorgeeft. Een goede JSON-serializer bewijst evenmin dat een mislukte opdracht het oude rapport bewaart. Een integratietest verbindt daarom de onderdelen die samen de gebruikersopdracht uitvoeren.

Onze tests gebruiken de bestaande main-functie met expliciete argumenten. Zij maken tijdelijke bestanden, lezen de werkelijk geschreven uitvoer en vergelijken de resultaten. Daarvoor hoeven zij geen subprocess of netwerkdienst te starten.

Een test is een echte uitvoering

Een unittest-suite voert een assertion uit
import unittest

class Totals(unittest.TestCase):
    def test_sum(self):
        self.assertEqual(20 + 15, 35)

suite = unittest.defaultTestLoader.loadTestsFromTestCase(Totals)
result = unittest.TestResult()
suite.run(result)
print(result.testsRun)
print(result.wasSuccessful())
Verwachte uitvoer
1
True

Het voorbeeld laat de unittest-loader een test vinden en de suite werkelijk uitvoeren. Het resultaat meldt hoeveel tests zijn gelopen en of zij geslaagd zijn. Alleen een functienaam met test erin is nog geen uitgevoerde controle.

De meegeleverde DeliveryTests bevat alvast een tijdelijke werkmap en een source-helper. Met addCleanup wordt de map ook na een mislukte assertion opgeruimd. Iedere test krijgt zo eigen bestanden en een eigen beginstand.

Verwachtingen komen uit de afspraak

De drie demonstratieregistraties bevatten zestig, vijfenveertig en veertig minuten. Hun totaal is 145, met balie1/45 en bouw2/100. Deze waarden leg je onafhankelijk vast in assertions.

Laat make_report niet eerst de verwachte waarde berekenen voor een test van dezelfde opdracht. Een fout in die functie zou dan zowel de verwachting als het echte resultaat veranderen. Je vergelijking kan groen blijven terwijl de gebruiker een verkeerd rapport ontvangt.

Kleine grenzen maken regressies zichtbaar

Een selectie van alleen twee oktober levert precies de balie-registratie op. Dat korte geval onderscheidt een genegeerd filter van een echte selectie en maakt het uitsluiten van de einddag zichtbaar. Controleer ook de periodemetadata, zodat de betekenis van het bestand vastligt.

Bij ongeldige invoer hoort een ander pad. Maak vooraf een herkenbaar oud rapport, voer de verkeerde bron in en controleer zowel status twee als de ongewijzigde inhoud. Eén van die twee voorwaarden alleen dekt het herstelcontract niet.

Veelgemaakte fout: bestaan verwarren met correctheid

Een bestand met de extensie csv kan nog steeds JSON bevatten. Een bestaande file kan ook een onvolledige tabel zijn. Lees daarom de echte CSV-rijen en vergelijk de kop én de gegevenswaarden.

Een verkeerde verwachting levert een echte failure
import unittest

class Totals(unittest.TestCase):
    def test_sum(self):
        self.assertEqual(20 + 15, 40)

suite = unittest.defaultTestLoader.loadTestsFromTestCase(Totals)
result = unittest.TestResult()
suite.run(result)
print(result.testsRun)
print(result.wasSuccessful())
print(len(result.failures))
Verwachte uitvoer
1
False
1

De tweede suite heeft een echte assertion die faalt. Dat is bruikbaar bewijs dat de verwachting iets onderscheidt. Een skip, expectedFailure of ontbrekende test levert diezelfde zekerheid niet.

De toets controleert ook je tests

De oefenomgeving draait je geselecteerde unittest-test eerst tegen de juiste projectbestanden. Daarna krijgt dezelfde test volledige projectkopieën met concrete regressies, bijvoorbeeld een verkeerd totaal of een beschadigd oud rapport. Zo wordt zichtbaar of jouw assertions de afgesproken fout daadwerkelijk afwijzen.

Een onverwachte programmeerfout in de test telt daarbij niet als een gevonden regressie. De verkeerde projectvariant moet op een echte assertion stuklopen. De juiste variant moet volledig slagen, zonder overgeslagen controles.

Opleveren met concrete grenzen

Deze regressies komen boven op de gerichte parser-, model-, I/O- en foutproeven uit de vorige lessen. Zij bewijzen de gekozen opdrachten en gevallen, samen met de verklaarde aannames over de uitvoermap. Een wijziging is pas af wanneer die relevante controles opnieuw zijn uitgevoerd.

AAN DE SLAG 0/4
1

Een volledig JSON-rapport controleren

Vul DeliveryTests.test_complete_report(self) als echte unittest-test in. Gebruik eigen tijdelijke bestanden en roep hours.cli.main met expliciete argv aan. Voor de drie demo-registraties zijn de status0, het aantal3, het totaal145 en de alfabetische teamregels balie1/45 en bouw2/100. Controleer de echte JSON-uitvoer, zonder je verwachting met de productfuncties te berekenen.

2

Een kleine periode als regressie vastleggen

Vul test_date_window in. Kies start=end=2026-10-02 voor dezelfde bron. Verwacht status0, periodemetadata voor die dag en precies balie1/45: één registratie en45 minuten. Je test moet zowel genegeerde filters als een uitgesloten einddag afwijzen.

3

Een invoerfout bewaart het oude rapport

Vul test_input_error_preserves_report in. Maak een onbekend team in de bron en een vooraf bestaand rapport met herkenbare tekst. Verwacht status2 én exact behouden oude tekst. De test moet een verkeerde successtatus en het beschadigen van het oude rapport afzonderlijk herkennen.

4

De CSV-overeenkomst bewaken

Vul test_csv_summary in. Kies --format csv bij de drie demo-registraties. Verwacht status0 en de echte CSV-rijen:team,sessions,minutes; balie,1,45; bouw,2,100. Gebruik een echte unittest-assertion, geen skip of expectedFailure. De test moet JSON-in-CSV en een ontbrekende kop herkennen.

Samenvatting

  • Integratietests gebruiken echte bronnen, argumenten en uitvoerbestanden.
  • Een onafhankelijke verwachting voorkomt dat een productfout zichzelf goedkeurt.
  • Een bruikbare test slaagt op de juiste variant en herkent concrete regressies.
test_delivery.py
UitvoerPython
›
›_

Hier komt je resultaat.

Voer je code uit en ontdek
wat je hebt gemaakt.

0/4 stappen
EVEN MEEKIJKEN

Bekijk hoe het kan.

Je mag de oplossing bekijken. Deze poging telt dan niet mee als afgeronde les. Met Reset kun je daarna opnieuw zelf oefenen.