Unittesten

Unittesten is een methode om softwaremodulen of stukjes broncode (units) afzonderlijk te testen. Bij unittesten zal voor iedere unit een of meer tests ontwikkeld worden. Hierbij worden dan verschillende testcases doorlopen. In het ideale geval zijn alle testcases onafhankelijk van andere tests. Eventueel worden hiertoe zogenaamde mockobjecten gemaakt om de unittests gescheiden uit te kunnen voeren.

Doelstelling

Het doel van unittesten is om functionele units onafhankelijk van elkaar te kunnen testen op correcte werking. Deze gedachte vloeit voort uit modulaire softwareontwikkeling.

Unittest tegenover gebruikerstest

Unittesten is typisch een taak voor de softwareontwikkelaar of testteam. Dit in tegenstelling tot eindgebruikertests. Ook het doel is anders.

  • Met unittesten controleert de ontwikkelaar of delen van de software goed werken of blijven werken gegeven bepaalde invoer (correct of foutief).
  • Met gebruikerstesten controleert men in samenwerking met de gebruiker (of alleen de gebruiker) of de software reageert op de manier zoals de gebruiker verwacht dat hij zou reageren.

Wanneer voordelen?

Waar uiten zich de voordelen van unittesten?

Bij het aanpassen in de software

Unittesten is gebaseerd op het gebruik van testcases. Deze worden voorafgaand aan de test opgesteld, meestal zelfs tijdens het ontwikkelen van de software. De verschillende testcases vormen op deze manier een omschrijving van een goede werking van de unit. Wanneer in een later stadium aanpassingen of correcties uitgevoerd moeten worden op de unit, is betrekkelijk eenvoudig na te gaan voor de ontwikkelaar of de wijzigingen de unit in het gedrag niet hebben beïnvloed. De test die dan wordt uitgevoerd noemt men Regressietest.

Bij het integreren van softwaremodules

Unittesten gebeurt op afzonderlijke units, meestal door de ontwikkelaar. Als de ontwikkelaar tevreden is wordt de unit opgeleverd. De volgende stap is het testen van de geïntegreerde units in de Integratietests.

Bij het up-to-date houden van documentatie

Documentatie bijhouden van software is een van de lastigste en vervelendste klusjes. Meestal wordt dit niet goed gedaan, wat resulteert in grote verschillen tussen de documentatie en de software. Unittests en testcase omschrijvingen zou men kunnen beschouwen als "live" documentatie. Iedere wijziging (groot of klein, ontwerpwijziging of bugfix) zal getest moeten worden. Wanneer men dit doet op basis van unittesten, dan zijn de testcases de meest recente beschrijvingen van de correcte werking van een unit en vormen zij dus de meest recente documentatie van de software.

Beperkingen

Een unittest is beperkt tot de unit zelf. Dit betekent dat niet goed getest is hoe goed het systeem werkt wanneer de units geïntegreerd met elkaar zijn. Andere manieren van testen zullen deze tekortkoming van unittesten moeten compenseren. Daarbij geldt, net als bij iedere manier van testen, dat het nooit mogelijk is om voor alle mogelijk scenario's testcases op te stellen en hierop te testen.

Ondersteuning voor unittest op taalniveau

Sommige programmeertalen hebben directe ondersteuning voor unittesten. Hun grammatica zorgt voor directe toewijzing van unittesten zonder het importeren van extra bibliotheken. Daarnaast kunnen booleaanse condities binnen de unit uitgedrukt worden in dezelfde schrijfwijze als een booleaanse expressie in reguliere code, zoals de if en while instructies.

Programmeertalen met ondersteuning voor unittesten zijn:

Voorbeeld

PHP

Een voorbeeld van een unittest kan met een PHP-framework zijn voor het testen van de bekende rij van Fibonacci. De code base berekent de aantal opgevraagde cijfers van Fibonacci en serveert deze in numerieke volgorde vanaf het begin. De rij van Fibonacci is door het programma beperkt tot het genereren tussen 1 en 99.

Bij elke geslaagde test moet het antwoord ja zijn. Dit zijn de testvragen:

  1. Genereert het programma exact de eerste 15 cijfers van Fibonacci zoals opgevraagd?
  2. Is het programma wel beperkt tot het genereren van de eerste 99 cijfers van Fibonacci?
<?php declare(strict_types=1);

namespace Tests\Unit\Test;

use PHPUnit\Framework\TestCase;

class FibonacciTest extends TestCase
{ 
    //Genereert het programma exact de eerste 15 cijfers van Fibonacci zoals opgevraagd?
    /** @test */
    public function isWeergaveVijftien() : void {

        $output = $this->fibonacciSerie(15);
        $this->assertEquals(
            "0 1 1 2 3 5 8 13 21 34 55 89 144 233 377",
            $output
        );
    } 
    //Is het programma wel beperkt tot het genereren van de eerste 99 cijfers van Fibonacci?
    /** @test */
    public function isMaximumBeperkt() : void {

        $output = $this->fibonacciSerie(100);
        $this->assertNull(
            $output
        );
    } 

    // Het programma
    public function fibonacciSerie(int $length) : ?string {
        if($length < 1 || $length > 99) {
            return null;            
        }
        $a = 0;
        $b = 1;
        $output = "";
        for ($i=0; $i<$length; $i++) {
            $output .= $a . " "; 
            $c = $a + $b;
            [$a, $b] = [$b, $c];
        }
        return substr($output, 0, -1);
    }
} 
?>

Zie ook