Zoekformulier

Unit-testing en databases

Unit-testing is een methode voor kwaliteitsbewaking van software die sterk in opkomst is. Het kan er onder andere voor zorgen dat er minder bugs optreden bij het doen van aanpassingen in bestaande websites. Het schrijven van unit-tests voor webapplicaties die veel gebruik maken van een database was echter omslachtig en tijdrovend. iWink ontwikkelde een oplossing.

Wat is unit-testing?

Unit-testing (of unittesten) is een manier om stukken code automatisch te testen. Unit-testing bestaat uit het schrijven van kleine stukjes code die andere stukken code testen op correct functioneren. Alle testen samen vormen een krachtige methode voor kwaliteitsbewaking van het gehele product.

Verder ondersteunt unit-testing het veilig en feilloos doorontwikkelen van producten: wanneer nieuwe code geschreven wordt of oude code verandert, garandeert het draaien van unit-tests dat de kwaliteit van de code goed blijft en er geen nieuwe fouten ontstaan.

Voorbeeld

Een voorbeeld van een unit-test komt uit onze eigen projectadministratie. Wanneer een iWink medewerker een projectonderdeel afrondt, gaat er automatisch een e-mail naar de klant. Met een unit-test wordt bewaakt dat deze e-mail correct verzonden blijft worden wanneer er aanpassingen aan het systeem worden gedaan.

Voorbeeld van een geslaagde test (bron: www.simpletest.org) Voorbeeld van een geslaagde test (bron: www.simpletest.org)

Database ondersteuning

Hoewel unit testing dus in theorie ideaal klinkt, is er een probleem waar veel software ontwikkelaars tegenaan lopen, waaronder iWink. Software is geschreven om om te gaan met data en bewerkingen te doen op data. De code is dus afhankelijk van de data van een database, of deze nu de lijst met gebruikers specificeert met toegang tot Webbeheer, tekst voor uw webpagina of een complete product catalogus: iWink code werkt met deze data en zonder deze data kan de code niet voldoende getest worden.

Het gebruiken van bestaande data om iWink code te testen is echter geen optie: standaard data test niet goed wat er met code gebeurt in extreme situaties, bijvoorbeeld wanneer een gebruiker een cruciale fout maakt bij het invoeren van gegevens, de data gecorrumpeerd raakt of er met zeer afwijkende data gewerkt wordt (bijvoorbeeld een niet-Latijns alfabet).

Bovendien veranderen unit-tests continu de onderliggende data. Wanneer bijvoorbeeld een item door een unit-test uit de database verwijderd wordt om te testen of het verwijderen van bijvoorbeeld webpagina's goed gebeurt, verandert de database en zullen andere unit-tests falen.

Om deze problemen op te lossen, heeft het Lab software ontwikkeld om de database te simuleren in een gecontroleerde omgeving. De database waarop de code getest wordt, wordt aan het begin van elke serie testen opnieuw aangemaakt en aan het begin van elke individuele test schoongemaakt. Vervolgens wordt de database gevuld met data die speciaal is ontwikkeld door de schrijver van de test. Zo weten we zeker dat elke test in een door zichzelf gecontroleerde omgeving kan draaien.
 

Hoe ziet dat er uit?

class TaskTestCase extends UnitTestCase {
 function setUp() {

  $this->db = iWink_Test_Framework::db()
    ->withTable('gebruikers')
        ->withRecord($user_record1)
        ->withRecord($user_record2)
    ->withTable('todo')
        ->withRecord($task_record1)
    ->withTable('orders')
        ->withRecord($order_record1)
    ->withTable('personen')
        ->withRecord($persoon_record1)
    ->withTable('organisaties')
        ->withRecord($org_record1)
    ->withPMTables()
    ->and()->with()->noExpectations();

  iWink_Test_Framework::registerDB($this->db);

 }

 function tearDown() {
  iWink_Test_Framework::unregisterDB();
 }

 function testAutoNotifyCompleted() {

  // Zet een taak klaar om af te ronden
  $completion_task = Task::load(1);
  $completion_task->status = 'Open';

  // Zet staat op afgerond: er wordt nog geen mail verstuurd
  StateMachine::setState($completion_task,'Closed');
  $this->assertFalse(testMailer::$mails, 'Er horen op dit punt 
      geen e-mails te zijn verstuurd [%s]');

  // Save: er wordt een mailtje verstuurd naar intern
  $completion_task->save();
  $this->assertEqual(count(testMailer::$mails), 1, 'Er hoort 
      op dit punt 1 e-mail verzonden te zijn [%s]');

  // Inspecteer mailtje
  $mail = testMailer::$mails[0];
  $this->assertTrue(strpos($mail->Body,'TestTaak 1'),		
               'Titel van taak wordt niet in 
                e-mail genoemd [%s]');

 }
}

Open source

Als basis voor onze unit-tests gebruiken we SimpleTest, dat open-source beschikbaar is onder een LGPL licentie. Het benutten van deze software, die door de internet gemeenschap constant wordt onderhouden en vernieuwd, maakt het in ons unit-testing framework mogelijk diverse geavanceerde technieken te gebruiken, zoals het automatisch aanmaken van stubs en Mock objecten. Het is zelfs mogelijk tests te schrijven die een webpagina van iWink software laden in een virtuele browser, waarna er allerlei test gedaan kunnen worden op de kwaliteit van de pagina's die de gebruiker uiteindelijk te zien krijgt.

iWink zal in de toekomst steeds meer gebruik maken van deze geautomatiseerde tests om de kwaliteit van onze producten te bewaken en garanderen.
 

tags: database, kwailteit, open-source, simpletest, unit-testing