1.4-Software-Development-Principles

JUnit5 - Slecht Weer Tests

Voorwaarden

Voor dat je aan deze theorie pagina begint moet je weten wat lambda expressies zijn, of op zijn minst Anonymous klassen.

Inleiding

We kunnen er nu vanuit gaan dat je tests kunt ontwerpen die bevestigen dat je code werkt zoals verwacht. Je zult gebruikelijk bevestigen dat de code het juiste antwoord geeft wanneer je de juiste vraag stelt. Dit heet “Mooi weer testen” of “Het Blije Pad”.

Je hebt ook geleerd dat het checken van de juiste input en het gooien van excepties belangrijk is om juiste resultaten te bereiken. Dus de vraag wordt, hoe test je dat jouw code bepaalde waarden of situaties verwerpt. Met andere woorden, mijn code moet neet storten met een een exceptie in specifieke situaties. Kan ik dat testen? Dit heet “Slecht Weer Testen” of “Het Gevaarlijke Ravijn” (@TODO: Check deze term)

Op deze manier testen we beide situaties:

Executable interface

Om te testen dat code verkeerd kan gaan hebben we een setje instructies nodig die zouden moeten leiden tot een Exception.

Om onze assertion te voorzien van zo’n setje instructies gebruiken de de Executable interface:

@FunctionalInterface
public interface Executable {
	void execute() throws Throwable;
}

De execute() methode kan een aantal instructies uitvoeren zonder dat er invoer nodig is.

Voor de assertThrows method bieden we deze interface aan in de vorm van een lambda expressie:

// Create an instance of the Executable interface by referencing a method.
Executable r = MyClass::doStuff;
r.execute();

assertThrows

Om deze assertion methode te gebruiken is het belangrijk om lamda expressies te gebruiken of een anonymous class. (Kan ook alle tests classes een naam geven, maar dat wordt erg lang.)

De assertThrows bevestigd twee dingen:

Naderhand kun je de inhoud van de Exception verder analyseren met andere assert methoden.

De assertThrows methode verwacht twee argumenten, een is de klasse van de Exceptie die zou moeten optreden wanneer deze “fout” wordt gemaakt. En de tweede is een instantie van de Executable interface die de juiste instructies uitvoert om deze specifieke exceptie te veroorzaken.

@Test
public void AfterCallingConstructor_WhenAgeIsNegative_ThenThrowsIllegalArgument() {
    IllegalArgumentException ex = assertThrows(
		// This is the expected Exception.
        IllegalArgumentException.class,
		// This is code that should go wrong.
		() -> { Person p = new Person("John", -1); } 
    );	
	// Additional confirmation that the internal data is as expected.
	assertEquals("Expected message", ex.getMessage());
}

In dit voorbeeld, met een mooie Given_When_Then naam, wordt de assertThrows gebruikt om te bevestigen dat een dat een stukje code mis gaat. In dit voorbeeld gebruiken we een lambda expressie: () -> { Person p = new Person("John", -1); }

Je kunt natuurlijk ook geen anonieme Executable implementatie inzetten:

IllegalArgumentException ex = assertThrows(
    IllegalArgumentException.class, // This is the expected Exception.
    new Executable() {
        @Override
        public void execute() {
            Person p = new Person("John", -1);
        }
    }
);

“branch coverage” garanderen.

Wanneer jouw code meerdere redenen kan hebben om te falen, dan is het van vitaal belang om te bevestigen dat al deze redenen getest worden.

Het punt is dat ieder pad door de methode getest wordt. Wanneer het antwoord correct isk, maar ook wanneer een methode een fout zou moeten veroorzaken.

Grenzen opzoeken

Wanneer enkel waarden (we gaan even uit van nummers) binnen een specifiek bereik toegestaan is dan kan ik zeven (!) verschillende soorten tests bedenken:

Category Wat wordt getest? Voorbeeld bereik 13-25
1 Waarden lager dan het bereik falen. -15, 0 & 10
2 De waarde precies onder de ondergrens faalt. 12
3 De waarde precies binnen de ondergrens goed gaat. 13
4 Waarden binnen het bereik goed gaan. 15, 17 & 20
5 De waarde precies binnen de bovenggrens goed gaan. 25
6 De waarde net buiten de bovengrens faalt. 26
7 Waarden boven het bereik falen. 30, 100 & 1000

Daarnaast raden we het sterk aan om ook vreemde waarden te testen zoals: