[Dutch] Geautomatiseerd Testen Met Erlang/OTP en Travis-CI - Een Introductie.
Erlang/OTP is ontworpen voor het bouwen van grote, schaalbare, soft-realtime systemen met een hoge beschikbaarheid. Het testen van dergelijke systemen is niet eenvoudig, laat staan geautomatiseerd testen. Voor Erlang zijn er dan ook geavanceerde automatische test methoden beschikbaar.
De drie belangrijkste methoden worden hier kort besproken aan de hand van een test project. De methoden zijn:
Je cloned het project van Github met het volgende commando:
1
|
|
Voor het compileren van het project en uitvoeren van de testen gebruik je Rebar, een sophisticated build-tool for Erlang projects that follows OTP principles. Je bouwt Rebar als volgt:
1 2 3 4 5 6 7 8 9 10 |
|
Unit testing met EUnit
Je begint met de eenvoudigste test methode; EUnit. Dit is een unit testing bibliotheek voor Erlang. In een unit test controleer je of de functie goed werkt bij bekende input en resultaat. In dit voorbeeld heb je de functie addition
geimplementeerd in de module ci_quickstart_math
en twee assertions. (Je voert deze test uit op de commandline met: rebar get-deps compile eunit
):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
|
Het slechte nieuws is dat de waarde van deze test zeer laag is. Weet je nu zeker dat optelling goed gaat in alle gevallen? Het enige wat de test nu aantoont is dat:
addition(2,2) == 4
addition(1,1) /= 3
Stel, je verandert de implementatie van de function addition
in:
1 2 |
|
De testen slagen in dit geval, maar dit betekend niet dat de implementatie van addition
correct is.
Sterker nog; De argumenten zijn in dit geval 64-bit small integers, en die hebben een bereik van -576460752303423489 t/m 576460752303423488. Met twee argumenten, betekend dit dat er enorm veel verschillende input mogelijk is. En in de unit test controleer je er maar 3!?!? Ook al ben je een harde werker en test je wel 10! addities, in feite is de waarde van de unit test niet verbeterd en nog steeds erg laag.
Wat nu?
QuickCheck
Wat je eigenlijk wil is een test methode dat alle mogelijke input variaties genereerd en de bijbehorende output controleert. Deze methode heet QuickCheck. Voor Erlang zijn er een aantal QuickCheck frameworks beschikbaar:
Een Quickcheck test voor de addition
functie:
1 2 3 4 5 6 |
|
Voer de test uit door de Erlang Shell op te starten met ./shell.sh
en de volgende functie aanroep proper:quickcheck(ci_quickstart_math:prop_sum()).
Specifieke nummers worden niet getest. Je gaat nu controleren of de functie voldoet aan de eigenschap dat als je Y weer er afhaalt, je X overhoud.
{int(), int()}
genereerd tuples met twee random integers. De tuple wordt gebonden aan {X, Y}
door pattern matching. Standaard worden er 100 combinaties getest, en dit aantal voer je op met de numtests
optie: proper:quickcheck(ci_quickstart_math:prop_sum(),[{numtests,10000}]).
.
De uitdaging bij het werken met QuickCheck is het bedenken van de eigenschappen van de functie. Dit is lastiger dan het maken van een unit test. Sterker nog, het schrijven van de functie is vaak nog eenvoudiger dan het redeneren over de eigenschappen. Het positieve effect van QuickCheck op de kwaliteit van je code, en de manier waarop je als developer over je code nadenkt maakt deze tool een zeer waardevol onderdeel van je test gereedschapskist.
Common Test
Zoals bekend is Erlang uitermate geschikt voor het bouwen van concurrent, distributed en fault tolerant systemen. Om te controleren of je systeem werkt zoals verwacht, is complex.
Hiervoor is Common Test in het leven geroepen. Dit krachtige test framework is uitermate geschikt voor de ontwikkeling van pittige systeem tests. De inherente complexiteit van concurrent, distributed en fault tolerant systemen maakt Common Test complex. Hoe je een serieuze OTP applicatie op de pijnbank legt met CT valt derhalve buiten de scope van deze blogpost. Hier onder wel een minimaal Comment Test waarin de EUnit testen worden nagebootst door gebruik van pattern matching.
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
Continuous integration met Travis-CI
Stel, je hebt een flinke hoeveelheid Eunit, Common Test en Quickcheck testen geïmplementeerd. Het uitvoeren van alle geavanceerde testen duurt lang en belast je systeem fors. Om deze, en nog meer goede redenen, is Continuous integration aan te raden.
Er zijn legio systemen waarmee het mogelijk is om continuous integration voor Erlang op te zetten. In dit voorbeeld gebruik je het hosted systeem Travis-CI. Deze dienst ondersteunt Erlang, integreert met het populaire Github en zorgt voor een vliegende start. En het is gratis voor open source projecten.
Voorbereiding
Het build proces van Travis-CI configureer je via het .travis.yml
-bestand in de root van je repository. Een voorbeeld:
1 2 3 4 5 6 7 |
|
Travis-CI Setup
Deze video toont hoe je start met Travis-CI:
- Log in met je Github account.
- Ga naar de Travis-CI profile pagina.
- Schakel de gewenste Github repository in.
That’s it!
Travis-CI Success Run
Deze video toont hoe Travis-CI een geslaagde integration build rapporteerd:
Travis-CI Failure Run
Deze video toont hoe Travis-CI een mislukte integration build rapporteerd:
Als je e-mail adres in .travis.yml
staat, krijg je ook een e-mail notificatie dat de laatste commit de build gebroken heeft:
Als de fout verholpen is, krijg je de volgende e-mail als de build weer slaagt: