Dit is de vierde blog in een serie over de bouw van een app om spelerstatistieken bij te kunnen houden van de pitchers in een honkbalteam. Naast het schrijven van code voor de app, is testen en nog eens testen de enige manier om je applicatie goed werkend te krijgen. Tijdens het ontwikkelen van m’n app paste ik TDD ofwel Test Driven Development toe. Test driven development betekent dat je eerst je tests uitschrijft en daarna de software ontwikkelt. Initieel lopen alle tests in error en gaandeweg het ontwikkelen krijg je steeds meer geslaagde tests. Tot alles groen is, waarna het script als regressietest gaat fungeren. Je kan TDD handmatig of geautomatiseerd toepassen.
Test Driven Development
De eerste test, de meest basale, is of je de code kan compileren. Dat betekent dat je in ieder geval geen fouten in de code hebt gemaakt. De tweede teststap is het opstarten van je app in een emulator of op bijvoorbeeld een fysieke telefoon. Daarna volgen de testen om te bepalen of de losse classes zoals bedoeld werken? En uiteindelijk test je of de database wordt gevuld met de juiste gegevens na de gegeven input. Dat laatste kan je bijvoorbeeld testen met andere apps zoals DB Browser voor SQLite.
De eerste Compilatie ‘test’
Ofwel een ontwikkelaarstest. Kan jouw code worden gecompileerd? Zitten er geen schrijffouten (syntax fouten) in je code? Dan slaagt de test. Dit is best verraderlijk want alhoewel jouw code prima kan compileren, lijkt alles helemaal in orde. Maar…
Neem bijvoorbeeld onderstaande code:
Int a = 1;
Int b = 3;
Int antwoord = 5;
Print(a + b = antwoord);
Is dit correct?
Hard coding variables
Soms ontkom er je er niet aan om tijdelijk variabelen hard in je programmacode zetten. Dit doe je zodat je daar op een later moment met een query andere keuzes uit je database kan halen. Echter, als je dit vergeet en je testcases testen een te beperkt scenario, dan zal je deze hard coded variabelen niet kunnen ontdekken.
In een van m’n eerste testcases testte ik of je bij een bepaalde invoer de juiste waarde van een sessie getoond kreeg. Echter, ik testte 3 worpen met ieder 1 uitkomst. Dat levert altijd waarde 6 op. Maar de code kende voor de beste uitkomst de waarde 0 toe en voor de slechtste een waarde van 5. Dat had natuurlijk precies andersom gemoeten. Pas toen ik een testfout maakte, ik voerde namelijk een testscenario te weinig op, ontdekte ik deze fout.
Hoe werkt TDD (een voorbeeld):
Om de gebruikers gemakkelijk door m’n app te leiden heb ik extra code ingebouwd. Dit is het tonen van een melding als iemand voor ’t eerst een scherm opent. Om dit te realiseren moest ik een extra tabel in m’n database aanmaken, extra code in de verschillende schermen bouwen en ook code schrijven om na een eerste bezoek een vinkje te zetten dat het scherm al een eerste keer getoond is.
M’n eerste test scenario: Ik open de app voor ’t eerst en krijg een melding te zien dat ik op dit scherm kan inloggen.
Stap 1: Krijg ik een melding te zien?
Stap 2: Krijg ik de juiste melding tekst te zien?
Stap 3: Als ik op OK druk van de melding en opnieuw de app open krijg ik de melding dan niet te zien?
Resultaat:
In eerste instantie faalt test 1 (en uiteraard ook 2 en 3) want ik had nog geen code. Nadat ik een tabel met meldingen heb aangemaakt en de code heb toegevoegd gaat stap 1 op groen. En als ik de melding goed heb geschreven in de database zou stap 2 ook groen moeten worden. En uiteindelijk nadat ik code heb toegevoegd voor het eenmalig tonen van de tekst gaat stap 3 ook op groen.
Met uiteindelijk het resultaat als je alle stappen hebt doorlopen:
Voordelen van TDD
Het eerste voordeel van TDD en ook BDD (Behavour driven development) is dat je weet wat uiteindelijk het resultaat moet worden en dat je daar naar toe werkt. Met het tweede voordeel dat je dan ook heel makkelijk dergelijke scenario’s kan automatiseren met bijv. Appium of met frameworks als Cucumber/ Gherkin. Een derde groot voordeel is dat je samen met product owners, business en informatie analisten al dergelijke scenario’s kan uitwerken en koppelen aan user stories om de voortgang in een project bij te houden. En tenslotte is een voordeel dat je er ook voor kan kiezen om bepaalde stukken functionaliteit al in kleine increments naar productie te brengen. Hierbij kunnen bijvoorbeeld ook de database wijzigingen al naar productie. Want zolang er geen code is die data ophaalt, gebeurt er toch niets.
Het opzetten van scenario’s voor TDD kost tijd, maar de geïnvesteerde tijd betaalt zich uiteindelijk terug in duidelijke requirements, voorspelbare functionaliteit en goed te volgen en te automatiseren tests. Is alles groen, dan kan je naar productie! Of toch niet? 😉
Wil je jouw ervaring delen? of meer weten? Ik vind het leuk om met je te sparren.