Tag Archives: mockito

The Wicket framework is not TDD-friendly

Posted on by

The Wicket framework is somewhat deceptive when it comes to testing, especially TDD. The wicket tester is pretty good for integration tests. However, when trying to test individual components in a TDD manner, you’ll get bitten by the “final” keyword that appears quite frequently among the Wicket components. Mockito won’t help you, my favorite subclass-and-override technique cannot be applied. So, you’re on your own, implementing extra methods in order to get the component under test, which leads to frustration and lack of focus.

Essensen och kruxet med testdriven utveckling

Posted on by

När du förstått poängen med testdriven utveckling kommer givetvis krånglet. Så hur tar man sig vidare?

Vi börjar med poängen så att vi är överens om vad vi menar.

Testdriven utveckling (TDD) säger att man först skriver ett test som fallerar (viktigt), sedan implementerar man så att det inte längre fallerer.

I det läget tar man sig en funderare om man tycker att designen och kodstrukturen är enklast möjliga. Om inte så fixar man till den, utan att ändra vad koden gör, refactor på engelska. Eftersom de tester man har, går igenom så är det tryggt att ändra implementationen.

Vi fortsätter sedan med ett nytt varv, test – implementation – refactor.

Enkelt så långt, men vad är poängen? Det finns flera poänger.

För det första så beskriver ett test vad som skall göras medan implementationen beskriver hur det ska göras. Testerna blir därmed specifikationer skrivna i ett formellt språk, Java (eller vad som gäller för projektet).

För det andra, eftersom testet skrivs innan implementationen så blir designen av gränssnittet gjort utifrån en brukare (testet) vilket blir bättre än om det görs med utgångspunkt i hur implementationen är utformad.

För det tredje så blir det av att skriva tester vilket inte är fallet om man skriver dem efteråt. Täckningsgraden för tester skrivna efteråt blir dessutom betydligt lägre eftersom det oftast blir svårt att komma åt delar av implementationen.

Motivationen att skriva tester för kod som uppfattas som fungerande är extremt låg.

Att det finns automatiskt exekverande tester är en kritisk framgångsfaktor. All kod behöver förändras, men kan säga att underhåll av en kodrad egentligen börjar så fort den är skriven.

Med automatiserade tester kan jag ändra i befintlig kod med större trygghet. Testerna specificerar ju vad som är korrekt så om jag ändrar något som går utanför det, så märker jag det direkt.

Det var essensen, så vad är då kruxet?

Det absolut vanligaste problemet med införandet av TDD är att det finns väldigt mycket kod som inte har automatiska tester. När man vill införa TDD så står denna kodmängd framför en som ett oöverstigligt berg.

Tanken är att nästa ändring som jag inför ska jag göra testdrivet, d v s skriva ett test som visar vad som ska hända, konstatera att det inte händer och sedan ändra så att det händer. Men koden jag ska ändra i, den har inga tester och är inte förberedd för det!

Så antingen struntar jag i TDD och ändrar ändå, som förut. Tar det försiktigt och rör ingenting som verkar krångligt. Kör lite informella tester och hoppas att testarna ska upptäcka eventuella fel. Förmodligen gör de det och så får jag tillbaka problemet någon tid senare när jag hunnit glömma alldeles för mycket. Eller så biter jag ihop för jag vill inte gå den vägen en gång till.

Det får kosta om det vill, bara jag slipper idissla varje ändring flera gånger.

Nu infinner sig problemet att arkitekturen är inte utformad så att jag lätt kan införa tester. Den komponent jag ska ändra i är beroende av flera andra komponenter som jag inte tänkt mig skulle behöva blandas in. I synnerhet som dessa i sin tur är beroende av ytterligare andra komponenter.

Här krävs att jag tar till något som isolererar komponenten från omgivande komponenter. Det finns flera knep, bl a olika ramverk som simulerar komponenter (mocking) och bara skickar tillbaka fördefinierade resultat. Min favorit för Java är Mockito.

Ibland räcker det dock med att ärva eller implementera gränssnitt och definera metoder som skickar givna svar.

Tyvärr behöver vi något mer. Även om vi lyckas begränsa komponenten så att den inte anropar kringliggande komponenter så vet vi inte om vi har haft sönder den eftersom vi inte har någon formell definition på "trasig" respektive "fungerande".

Vad vi kan göra då är att ta ett fingeravtryck. Innan vi ändrar något så skriver vi ett eller flera tester som är bara till för att generera utdata. Vi försöker skapa ett avtryck av hur komponenten beter sig. När vi sedan ändrar i komponenten så kan vi se om utdata förändrats på något oväntat sätt. I så fall kan vi gå in och analysera vad det berodde på och om det ska anses vara fel eller rätt.

Några böcker:
"Test Driven", av Lasse Koskela.
"Working effectively with Legacy Code", av Michael Feathers

Wicket + Mockito = Love

Posted on by

I’ve survived my first Rocket Day. RD are our seminars at Crisp where we talk for half a day on a subject of choice. Mine was Test Driven Development with Wicket and Mockito.

I chosed to do a live coding performance as I liked to do a very down-to-earth, practical seminar.

The slides are currently in swedish but I will translat them to english. Later. ūüėČ

However, most of you read swedish so I have published them here.