Testen, testen, testen

Je kan van alles automatisch testen, maar handmatig nog het een en ander controleren kan nooit kwaad.

Bij software-ontwikkeling is het steeds gebruikelijker om gebruik te maken van testen. Hierbij schrijven we naast de programmacode zelf ook een stuk software dat de code controleert. Een heel versimpeld voorbeeld voor de niet-programmeurs onder ons: Als we ergens een functie moeten toevoegen die twee stukken tekst aan elkaar plakt, kan je een extra controle toevoegen die test of de functie doet wat hij moet doen.

"Test driven development" gaat nog een stapje verder: de programmeur schrijft eerst de controle die test of de functie goed werkt, daarna draait hij alle testen waarbij er als het goed is een foutmelding (ERROR) in testresultaten staat. Tot slot schrijft hij de werkelijke functie en controleer je opnieuw met het draaien van de testen of de functie nu naar behoren werkt.

Een voorbeeld in Python:

>>> def combineer(a, b):
...     return a+b
...
>>> combineer("plak deze tekst", "aan elkaar")
'plak deze tekstaan elkaar'

Nu is dit een behoorlijk lelijke plakfunctie. Ik zou kunnen verwachten dat mijn 'combineer' iets intelligenter is en spaties toevoegt. Van te voren kan ik dan (test driven) in mijn tests de volgende routine toevoegen:

assert combineer("dit is","een tekst") == "dit is een tekst"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AssertionError

Het 'assert' (neem aan) commando geeft direct een foutmelding want dit levert de functie niet terug. De combineer-functie is te verbeteren:

>>> def combineer2(a, b):
...     return a.strip() + " " + b.strip()

>>> assert combineer2("dit is","een tekst") == "dit is een tekst"
>>> assert combineer2("dit is "," een tekst") == "dit is een tekst"

En weg zijn de foutmeldingen. Ik probeer als programmeur al wat 'randgevallen te ondervangen door eerst extra witruimte van de tekst af te snoepen voordat ik de tekst aan elkaar plak om extra spaties te voorkomen, strip() verwijdert witruimte voor en achter een tekst. Legaal witwassen!

>>> assert combineer2(1, 2)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in combineer2
AttributeError: 'int' object has no attribute 'strip'

Onze functie faalt jammerlijk zodra in plaats van twee stukken tekst (strings) getallen voer (int), en zo kunnen we onze tests en functies uitbreiden en uitbreiden. Dit is een heel summier voorbeeld van hoe we bij het programmeren onze code van te voren (of achteraf) kunnen controleren met testen. De bovenstaande voorbeelden zijn 'unit tests', we testen 1 functie op gewenste in- en uitvoer.

De voordelen

Bij het werken aan websites en web-applicaties is het met veel uitgebreidere testmogelijkheden dan 'assert' ook te testen of als ik een online formulier invul met mijn voor- en achternaam in de daarop volgende pagina ik ook met mijn volledige naam wordt bedankt. Tegenwoordig kunnen we daarin zelfs dynamische websites testen doordat testprogramma's op de achtergrond een op afstand bestuurbare webbrowser starten. Ook voor niet programmeurs is er met programma's als Selenium heel veel automatisch te testen zonder iedere keer handmatig door een website heen te moeten klikken.

Eerst maar het nadeel: het schrijven/bouwen van testen, of dit nu in code is of integratietests met tools als Selenium kost in het begin tijd en tijd is geld. En ook bij het aanpassingen in een applicatie of website moet de programmeur de testen bijwerken. Maar de voordelen zijn er ook: bij uitbreidingen van het project en de code gaat een test als hij goed geschreven is vrij snel kapot en ziet de programmeur dat zijn onschuldige aanpassing eerder vastgelegde aannames kapotmaakt.

Het 'non plus ultra' bij testen zijn de automatische testen die automatisch op de achtergrondgedraaid worden nadat een programmeur een stukje code heeft toegevoegd aan een project: continous integration. Breekt zijn toevoeging één of meerdere testen dan krijg hij hiervan automatisch bericht. En baas boven baas: door automatisch testen te draaien bij elke code-aanpassing is zelfs het uitrollen van nieuwe code te automatiseren. Als alle tests 'ok' zijn, wordt vervolgens ook de applicatie of de website automatisch bijgewerkt en gedistribueerd/live gezet, continuous delivery.

Jaja, dat gaat zal wel...

tevredenheidsonderzoek 1

Dat was wel een heel lang bruggetje maar een mooie gelegenheid om iets over testen uit te leggen op ons blog. Vanochtend keek ik  vertwijfeld in mijn e-mail IN-vak. Daar stond een dringende herinnering van TNS-NIPO over de onderhoudsbeurt die mijn Volkswagen pas heeft gehad.Of ik toch maar zo vriendelijk wilde zijn het onderzoek alsnog in te vullen om mijn garage te beoordelen. Maar geen link te bekennen naar de enquête, foutje? Ik ben toch niet gek?

De originele uitnodiging erbij gezocht (de gewone consument was allang afgehaakt), maar ik werd toch nieuwsgierig naar deze 'fout' vanuit mijn test-nieuwsgierigheid. Ook daar stond geen link in. Zo dom kunnen ze toch niet zijn bij NIPO en Volkswagen? Wat blijkt: mijn web-email interface laat standaard, en dat is bij de meeste webmail diensten trouwens zo, geen afbeeldingen zien.

Pas na het toestaan van het laden van afbeeldingen kwam er opeens een grote 'start' knop in de tekst te staan. Daar gaat je response ratio, directeur Volkswagen Nederland! Maar was dit automatisch te testen geweest?

tevredenheidsonderzoek 2