måndag 7 december 2009

Unit testing success story!

Jag var bara tvungen att skriva en liten glädjepost om mitt första riktiga äventyr med unit testing.
Jag har under de senaste dagarna lagt till några nya funktioner i en grafisk kontroll. Den består i stort av en datagridview med ett antal rader och kolumner. Vissa rader är summor av ovanstående rader, vissa kolumner är summa av radens värden. Alltså, det finns lite relationer raderna och kolumnerna emellan.
I samband med att jag gjorde de nya funktionerna skrev jag i princip om hela kontrollen och dess affärslogik för att göra den mera testbar. Det verkade som en liten lagom prototyp. Och det var det.

För att bara beskriva läget före min unit testing refactoring, såg det ut ungefär så här:

  • Inga unit tests
  • Grafisk kontroll: Specialhantering för alla typer av rader och kolumner, kontroll mot konstanter och vissa magic numbers. Mycket kontroll av inmatade värden och omvandling från string till int.
  • Coordinator: Specialhantering av samma konstanter, 150 rader kod. 
  • Affärsobjekt: Ärvda versioner av riktiga affärsobjekt för att kunna blanda affärsobjekt med rena summeringsrader och kolumner. Konstanter och magiska siffror lite här och där.
  • Acceptanstest: Starta applikationen. Prova funktion 1, funkade inte. Ändra lite. Prova igen. Prova funktion 2, funkar! Prova den tredje funktionen, funkade inte. Ändra. Funkar! Prova lite till. Nu funkar inte funktion 1. Osv osv. Nervöst inför releasen... Buggfix redan första dagen.

Och så efter...

  • 40 unit tests, all green!
  • Grafisk kontroll: Bara hantering av hur cellerna ska se ut, hur de formatteras mm. Hämta värde och skriva värde till och från affärsobjekten sker med en enda enkel metod. 
  • Coordinator: En konstruktor och två properties. Det är allt.
  • Affärsobjekt: GUI wrappers som ibland håller referenser till affärsobjekt, ibland inte. Hel uppsatta för att på bästa sätt stödja GUI programmeringen. Och helt testbara!
  • Acceptanstest: Allt funkar med en gång! Iallafall ser det ut så...
  • Känns grymt bra inför releasen!
Med andra ord, att skriva unit tests för min lilla funktionsändring gjorde inte bara att jag fick mer förtroende att den fungerar. Det gjorde också lösningen betydligt bättre eftersom en testbar arkitektur helt enkelt är en bra arkitektur. Testbarhet motverkar nämligen "fix-och-trix-lösningar" som jag lätt faller tillbaka till. Tyngdpunkten på funktionerna ligger i affärslogiken. GUI:t hanterar bara grafisk representation.

Sen kan man säga vad man vill om att jag kanske även utan unit tests borde sett att lösningen... ja...sög.
Men det är skit samma nu. Med hjälp av en unit testing utflykt och genom att tänka på testbarheten blev det en självklarhet även för mig.

Att inte skriva unit tests i fortsättningen känns otänkbart. Nu är de här för att stanna, för den känsla jag nu har inför det jag presterat och inför en stundande release är något jag vill vänja mig vid.


Ett litet citat på vägen, som inte alls har med ämnet att göra, men som var så bra. Andy Hunt sa i sitt keynote på Öredev 2007 på temat "Accidental Complexity", dvs saker som är komplext utan att det egentligen finns skäl till det:
XML is like kids. They start of small and cute. Then they grow.

Over and out!

Dagens kodarmusik: Riva - Time is the healer (Armin van Buuren remix)

Inga kommentarer:

Skicka en kommentar