Unit Testen

linked/18663/52557Β 

1 Wat is testen? Waarom is het belangrijk?

🎯 Leerdoelen

πŸ’‘ Uitleg

Testen betekent controleren of je code het juiste doet. Als je iets verandert, wil je zeker weten dat het nog steeds werkt. Denk aan:

Daarom testen we onze code – om fouten te voorkomen en vertrouwen te krijgen in wat we gemaakt hebben.

πŸ“š Testsoorten

Er zijn verschillende soorten testen. Hieronder zie je een overzicht:

Testsoort Wat test je? Voorbeeld
Unit test Één functie of klein onderdeel Klopt bereken_korting()?
Integratietest Samenwerking tussen onderdelen Voegt bereken_korting() + bereken_verzendkosten() alles goed op?
Systeemtest Het hele programma Werkt de volledige webshop van begin tot eind?
Acceptatietest Voldoet het aan de wensen van de gebruiker? Kan de klant een product kiezen en succesvol bestellen?

In deze lessenserie focussen we op unit tests: kleine, duidelijke tests waarmee je functies controleert.

πŸ› οΈ Opdracht 1 – winkelmandje.py

Maak een nieuw Python-bestand aan met de naam winkelmandje.py en doe het volgende:

  1. Schrijf een functie bereken_totaalprijs(prijzen) die een lijst van prijzen optelt.
  2. Voorbeeld: bereken_totaalprijs([2.50, 4.00, 3.25]) moet 9.75 opleveren.
  3. Print het resultaat van je functie met verschillende lijsten.
  4. Probeer ook een lege lijst – wat gebeurt er?

🧠 Reflectie

πŸ“€ Inleveren

2 Je eerste unit test schrijven

🎯 Leerdoelen

πŸ’‘ Uitleg

In de vorige les heb je een functie gemaakt die de totaalprijs berekent van een lijst met bedragen. Nu ga je leren hoe je automatisch kunt testen of die functie goed werkt.

Hiervoor gebruik je de module unittest. Je schrijft testfuncties waarin je verwacht wat de uitkomst moet zijn. Als die klopt, krijg je een groene melding. Als die fout is, zie je precies waar het misgaat.

Voorbeeldtest:

import unittest

def bereken_totaalprijs(prijzen):
    totaal = 0
    for prijs in prijzen:
        totaal += prijs
    return totaal

class TestTotaalprijs(unittest.TestCase):
    def test_drie_bedragen(self):
        self.assertEqual(bereken_totaalprijs([2.50, 4.00, 3.25]), 9.75)

    def test_lege_lijst(self):
        self.assertEqual(bereken_totaalprijs([]), 0)

    def test_een_bedrag(self):
        self.assertEqual(bereken_totaalprijs([5.00]), 5.00)

    # def test_nog_een_bedrag(self):
    #    self.assertEqual(bereken_totaalprijs([5.00, 2.00]), 8.00)

if __name__ == '__main__':
    unittest.main()

Je voert het testbestand uit met:

python totaalprijs_test.py

πŸ› οΈOpdracht 1

Maak regel 9 en 10 actief. Voer het bestand opneuw uit. Wat zie? Kna je verklaren wat er gebeurt?

πŸ› οΈ Opdracht 2 – totaalprijs_test.py

Je gaat nu je eigen functie bereken_totaalprijs() uit les 1 testen.

  1. Maak een nieuw bestand aan: totaalprijs_test.py.
  2. Kopieer je functie bereken_totaalprijs(prijzen) uit winkelmandje.py.
  3. Schrijf een testklasse TestTotaalprijs waarin je de functie test met unittest.
  4. Schrijf minstens drie tests:
    • Lijst met meerdere bedragen (bijv. [2.50, 3.50]) β†’ controleer of totaal klopt.
    • Lege lijst β†’ verwacht 0.
    • Lijst met één bedrag β†’ verwacht dat bedrag.
  5. Voer je bestand uit in de terminal met python totaalprijs_test.py.

🧠 Reflectie

πŸ“€ Inleveren

3 Testen met lijsten en tekst

🎯 Leerdoelen

πŸ’‘ Uitleg

Veel programma's werken met lijsten van gegevens, zoals producten of gebruikers. Het is belangrijk dat je functies goed testen of iets voorkomt in een lijst, of hoeveel elementen erin zitten.

Stel, je hebt een lijst met producten:

producten = ["kaas", "melk", "brood"]

Dan kun je bijvoorbeeld een functie maken die kijkt of een product voorkomt:

def zoek_product(lijst, naam):
     product_gevonden = gezochte_product_naam in product_lijst
    
    return product_gevonden

En die functie testen met:

self.assertTrue(zoek_product(["melk", "brood"], "melk"))
self.assertFalse(zoek_product(["kaas", "brood"], "cola"))

πŸ› οΈ Opdracht 1 – producten_test.py

  1. Maak een nieuw bestand producten_test.py.
  2. Schrijf een functie zoek_product(lijst, naam) die True geeft als het product in de lijst staat.
  3. Maak een testklasse TestProductZoeken.
  4. Schrijf drie tests:
    • Zoek naar een bestaand product β†’ assertTrue
    • Zoek naar een niet-bestaand product β†’ assertFalse
    • Zoek in een lege lijst β†’ assertFalse
  5. Voer je testbestand uit met python producten_test.py.

Uitbreiding (optioneel)

Maak ook een functie tel_producten(lijst) die het aantal producten telt, en schrijf daar een test voor met assertEqual.

🧠 Reflectie

πŸ“€ Inleveren

4 Fouten en assertRaises

🎯 Leerdoelen

πŸ’‘ Uitleg

In Python krijg je een foutmelding (ofwel: exception) als er iets misgaat, zoals delen door nul of een ongeldig type.

Stel je schrijft deze functie:

def deel(a, b):
    return a / b

Als je deel(10, 0) probeert, krijg je deze fout:

ZeroDivisionError: division by zero

In een goede functie wil je zulke fouten voorspelbaar en controleerbaar maken, bijvoorbeeld zo:

def deel(a, b):
    if b == 0:
        raise ValueError("Delen door nul is niet toegestaan")
    return a / b

Je kunt dan testen of de fout netjes wordt afgehandeld, met:

with self.assertRaises(ValueError):
    deel(10, 0)

πŸ› οΈ Opdracht 1 – deel_test.py

  1. Maak een nieuw bestand deel_test.py.
  2. Schrijf een functie deel(a, b) die:
    • Een ValueError geeft als b == 0
    • Anders de uitkomst van a / b teruggeeft
  3. Maak een testklasse TestDelen met drie tests:
    • Deel 10 door 2 β†’ verwacht 5.0
    • Deel 9 door 3 β†’ verwacht 3.0
    • Deel door 0 β†’ verwacht ValueError met assertRaises
  4. Voer je tests uit met python deel_test.py.

🧠 Reflectie

πŸ“€ Inleveren

5 Testen van klassen met setUp()

🎯 Leerdoelen

πŸ’‘ Uitleg

In grotere programma’s werk je vaak met klassen. Die bestaan uit eigenschappen (zoals naam en prijs) en methodes (zoals korting berekenen).

Bijvoorbeeld een klasse Product:

class Product:
    def __init__(self, naam, prijs):
        self.naam = naam
        self.prijs = prijs

    def prijs_incl_btw(self):
        return self.prijs * 1.21

Als je zo'n klasse vaak moet testen, wil je niet steeds opnieuw een object aanmaken in elke test. Daarom gebruik je setUp():

class TestProduct(unittest.TestCase):
    def setUp(self):
        self.product = Product("muis", 10.00)

    def test_naam(self):
        self.assertEqual(self.product.naam, "muis")

    def test_prijs(self):
        self.assertEqual(self.product.prijs, 10.00)

    def test_prijs_incl_btw(self):
        self.assertAlmostEqual(self.product.prijs_incl_btw(), 12.10)

πŸ› οΈ Opdracht 1 – product_test.py

  1. Maak een nieuw bestand product_test.py.
  2. Schrijf een klasse Product met:
    • Eigenschappen naam en prijs
    • Methode prijs_incl_btw() die 21% btw toevoegt
  3. Maak een testklasse TestProduct waarin je in setUp() een Product aanmaakt.
  4. Voeg minimaal drie tests toe:
    • Test of de naam klopt
    • Test of de prijs klopt
    • Test of de prijs inclusief btw ongeveer klopt (gebruik assertAlmostEqual)

🧠 Reflectie

πŸ“€ Inleveren

6 Edge cases en grenswaarden

🎯 Leerdoelen

πŸ’‘ Uitleg

Een edge case is een grensgeval of een extreme situatie waarin je functie getest wordt. Zulke gevallen zorgen vaak voor fouten als je er niet vooraf aan denkt.

Voorbeelden van edge cases:

Voorbeeld: verzendkosten berekenen

Stel, je schrijft een functie die verzendkosten berekent op basis van het aantal producten:

def bereken_verzendkosten(aantal):
    if aantal <= 0:
        raise ValueError("Aantal moet positief zijn")
    elif aantal <= 3:
        return 2.50
    elif aantal <= 10:
        return 5.00
    else:
        return 0.00

Je kunt dan tests schrijven voor grenswaarden zoals 3, 4, 10 en 11.

πŸ› οΈ Opdracht 1 – verzendkosten_test.py

  1. Maak een nieuw bestand verzendkosten_test.py.
  2. Schrijf een functie bereken_verzendkosten(aantal) met de volgende regels:
    • 1 t/m 3 producten β†’ €2,50
    • 4 t/m 10 producten β†’ €5,00
    • Meer dan 10 producten β†’ gratis
    • 0 of minder β†’ ValueError
  3. Schrijf een testklasse met tests voor:
    • bereken_verzendkosten(1) β†’ €2,50
    • bereken_verzendkosten(3) β†’ €2,50
    • bereken_verzendkosten(4) β†’ €5,00
    • bereken_verzendkosten(10) β†’ €5,00
    • bereken_verzendkosten(11) β†’ €0,00
    • bereken_verzendkosten(0) β†’ foutmelding (assertRaises)

🧠 Reflectie

πŸ“€ Inleveren

7 Eindopdracht – Testen in de praktijk

🎯 Leerdoelen

πŸ’‘ Uitleg

In deze les werk je aan een kleine testset voor een programma naar keuze. Je kiest één van de twee scenario's hieronder. Je schrijft zelf de functies én de bijbehorende unittest-tests.

Scenario 1 – Webshop-functies

Je maakt een verzameling functies zoals:

Je schrijft voor elk van deze functies minstens 2 tests, waaronder minstens 1 edge case per functie.

Scenario 2 – Quiz-controlefunctie

Je schrijft een functie controleer_antwoord(gegeven, verwacht) die controleert of het antwoord juist is (hoofdletterongevoelig en spaties tellen niet mee).

Voorbeeld:

controleer_antwoord(" Python ", "python")  β†’ True

Schrijf meerdere tests voor deze functie:

πŸ› οΈ Opdracht – Kies en test

  1. Kies scenario 1 (webshop) of scenario 2 (quiz).
  2. Maak een nieuw testbestand (bijvoorbeeld webshop_test.py of quiz_test.py).
  3. Schrijf de functies zoals hierboven beschreven.
  4. Maak een testklasse en voeg minimaal 6 goed werkende tests toe (minstens 2 per functie).
  5. Zorg dat je ook minstens één foutmelding test met assertRaises.

🧠 Reflectie

πŸ“€ Inleveren


Revision #10
Created 6 June 2025 13:00:36 by Max
Updated 14 June 2025 20:38:29 by Max