Automatische tests met TestCafé en NUnit - TechBlog
In een vorige Xuntos TechBlog hebben we geschreven over de technologie stack die een van onze applicaties in de lucht houdt voor honderden gebruikers tegelijk. Vandaag bespreken we hoe we de kwaliteit van applicaties garanderen door het maken van tests die met één druk op de knop kunnen vertellen of de applicatie doet wat het moet doen. We praten hierover met Joost die zich tijdens zijn stage fulltime bezighoudt met het bouwen en verfijnen van deze tests.
Opstart
Joost begint te vertellen hoe hij bij Xuntos begonnen is met zijn stage: "De Haagse Hogeschool waar ik HBO ICT studeer, heeft een stagebank waar Xuntos is ingeschreven. Ik heb een aantal bedrijven die ik vond in die bank aangeschreven en Xuntos was een van de bedrijven waar ik op gesprek mocht komen. Tijdens dat gesprek kwam het onderwerp op de opdracht die ik zou gaan doen. Samen hebben we besloten dat ik voor een van de applicaties van Xuntos geautomatiseerde tests zou gaan verbeteren. Dat leek me erg leuk en uitdagend, nadat de opdracht goedgekeurd was door mijn stagebegeleider kon ik in september beginnen met het schrijven van de eerste tests."
TestCafé
Hierna gaat Joost verder over de start met TestCafé: "Mijn collega's hadden eerder al een aantal tests gebouwd met TestCafé en het eerste stuk van mijn stage zou ik die gaan uitbreiden en verbeteren. TestCafé is een tool waarmee door middel van TypeScript end-to-end tests ontwikkeld kunnen worden voor een applicatie. Je kan in code schrijven 'klik op deze knop en vul daarna in dit veld de volgende tekst in' waarna je de reactie van de applicatie kan controleren." Hij vertelt trots dat het "Heel cool" is om te zien dat TestCafé alle dingen die een gebruiker zou doen automatisch kan doen.
Het opzetten van de tests
Joost vertelt dan over zijn werkwijze voor het opzetten van tests: "Ik pakte het maken van tests vaak op door goed te kijken naar de user interface van de applicatie. Als ik een knop, link of formulier zag waar ik nog geen tests voor gemaakt had, dan schreef ik een lege test met een beschrijvende titel. Dan kon ik later al die lege tests langs lopen om ze één voor één uit te werken. Vaak bestond dat eerst uit de happy flow schrijven, dus een test waar alles gedaan wordt zoals het hoort, waarna ik ging bedenken 'hoe kan een gebruiker dit fout doen en hoe zou de applicatie dan moeten reageren?'."
Hij geeft met gepaste trots een voorbeeld hoe hij hiermee een bug gevonden had: "Zo is er in de applicatie een zoekveld waarmee door dingen gezocht kan worden. Ik vroeg me af wat er zou gebeuren als een gebruiker emoji in dat veld zou plakken, dus ik heb een test geschreven waar ik drie smileys in het veld laat plakken door TestCafé. Er is geen enkel item in de applicatie dat emoji in de naam heeft, dus ik verwachtte dat er geen resultaten zouden zijn. Dat waren er echter ruim veertig, dus de test faalde." Na dit aangekaart te hebben bij zijn collega's kreeg Joost groen licht om deze bug zelf op te lossen.
Onderhoudbaarheid verbeterd
"Toen ik begon waren er al wat tests gemaakt, maar deze bestaande tests waren niet onderhoudbaar opgezet. Zo was er bij iedere test los gedefinieerd welke HTML elementen gebruikt moesten worden. Dit is niet handig, als er namelijk iets aan het scherm verandert moet je op allerlei plekken je tests aanpassen," vertelt hij als we het hebben over de dingen die hij geleerd heeft over TestCafé. "Je kan veel beter een model van een pagina maken waarin je alle verschillende knoppen en velden als variabele definieert. Dan kan je in je tests die variabelen gebruiken, mocht er dan iets veranderen aan de pagina hoef je enkel die variabele aan te passen en dan werkt je test weer."
"Ook stonden de inloggegevens vast in de code. Dat is natuurlijk niet de bedoeling, al heb je wel inloggegevens nodig om de applicatie te kunnen testen. Ik heb daarvoor een testrunner gemaakt die bij het draaien eerst om de inloggegevens vraagt die je wil gebruiken, waarna de tests gedraaid worden met die gegevens." Joost vertelt ook over de twee verschillende versies die hij hiervoor gemaakt heeft: "Eerst had ik die test runner geschreven als een BATCH file, dat werkte voor mij prima. Tot een collega met een Macbook de tests wilde draaien. Een BATCH file werkt namelijk alleen op Windows en niet op MacOS, daarna heb ik een nieuwe versie gemaakt die geschreven is met Node.JS. Die werkt voor iedereen."
Unit tests van de backend
"Na ongeveer de helft van mijn stage ging ik door met het volgende onderdeel: Unit tests schrijven met NUnit. Waar TestCafé gebruik maakt van TypeScript, doe ik dit in C# omdat de backend daar ook in geschreven is." Joost geeft aan dat hij dit in het begin wel lastig vond: "De backend van de applicatie is best complex en dan een startpunt vinden was best een uitdaging. De interactie tussen de controllers, services en repositories duizelde me een beetje, zeker in combinatie met dat ik ze allemaal moest gaan mocken."
Moq mocks
Joost legt uit dat een unit test op zichzelf moet staan: "Als je met een unit test een methode wilt testen, dan moet die test niet afhankelijk zijn van databases of externe services. Daarvoor maak ik gebruik van het framework Moq, dat stelt me in staat van alle services en repositories mocks te maken. Mocks zijn een heel slim concept. Je zegt eigenlijk tegen het stuk code: 'Als jij ServiceA nodig hebt, dan krijg jij van mij MockServiceA'. Die MockServiceA heeft dezelfde methodes als ServiceA, maar dan kan je precies vaststellen wat het terug gaat geven. Hierdoor hoef je ServiceA dus niet te gebruiken, maar kan je test net doen alsof hij er toch is. Dit maakt de test veel betrouwbaarder, zo kan je ook testen wat de te testen code als een resultaat uit de service iets heel geks is. Zonder mocks zou je daar allerlei setup voor moeten doen, maar met een mock kan je gewoon aangeven wat het terug moet geven."
Joost laat weten dat hij een aantal tutorials nodig had om dat te begrijpen, maar dat hij er nu goed mee op weg is. "Ook begin ik inmiddels veel beter te begrijpen hoe de applicatie in elkaar steekt, enkel de code testen is toch wat abstracter dan TestCafé, maar niet minder leuk. Zeker niet als ik daardoor bugs kan vinden."
Coverlet
"Een van de andere dingen die het leuk maakt is de code coverage," vertelt Joost enthousiast. "Ik heb de tool Coverlet in het test project geïnstalleerd. Dat is een testcollector, een stukje software dat de resultaten van de unit tests verzamelt en vastlegt in een XML bestand. Dat XML bestand kan gebruikt worden om een rapport te genereren dat vertelt welk deel van de code precies getest wordt met de unit tests. Dat doet hij doormiddel van een percentage, maar ook zelfs op code regel niveau. In zo'n rapport kan je zelfs bij if statements zien of alle verschillende condities afgedekt zijn met de tests die gedraaid hebben." Bij de vraag of er een bepaald doel is qua code coverage antwoordt hij schuchter: "Nog niet echt, maar het gaat er vooral om dat de tests die er zijn van hoge kwaliteit zijn, zodat je er van op aan kan."
Tenslotte vragen we Joost of hij een stage bij Xuntos aan zou raden bij zijn medestudenten. "Ja, mits ze van web development houden. Er zijn leuke collega's en een goede bedrijfscultuur." Ben jij ook op zoek naar een (afstudeer)stage? Neem dan contact met ons op voor een toffe en interessante opdracht.
~ Joost is geïnterviewd door Victor Remmerswaal
Kennismaken met een kop koffie?
Wil je een vraag stellen of een kennismaking plannen?
Vul onderstaand formulier in.