Etiketter - Unit testing

Unit testing med Roy Osherove

Hade nöjet att under TechEd Europe delta i en session med Roy Osherove, som till vardags arbetar som chefsarkitekt hos Typemock och även skrivit boken ”The art of unit testing”. Det initiala sessionsnamnet var ”Unit Testing - Best practices”, vilket han efter en kommentar i sista minuten reviderat till ”Unit testing – Good practices”.

Vad är då ett unit test och vad definierar ett bra sådant?

Ett unit test är en metod som testar vissa antaganden mot en annan klass eller metod. Ett exempel på ett enkelt unit test är följande.

[Test]

public GetCityById_NegativeNumber_NameIsNull()

{

   City c = GetCityById(-1);

   Assert.AreEqual(c.Name, null);

}

Vi testar alltså om vår GetCityById metod returnerar null då vi skickar in ett negativt nummer som parameter. För att kunna skriva ett bra unit test måste vi dock först definiera vad som är ett integrationstest och vad som är ett unit test. Osheroves definition av ett unit test är:

  • Snabbt
  • I minnet
  • Inga externa beroenden (mot filsystem, databaser etc.)
  • Samma process
  • Automatiserat
  • Repeterbart
  • Konsekvent

När vi nu vet vad ett unit test är, kan vi med fördel dela upp våra unit och integrationstester i olika namespaces eller projekt. Genom att göra en uppdelning av våra tester har vi sedan en klar bild över vilka av våra tester som har externa beroenden, och vilka som vi kan köra som unittests.

En viktig sak Roy nämner är vikten av att lita på sina tester. Litar man inte på dem och använder debuggern för att dubbelkolla förlorar testet sitt syfte. En av anledningarna till att man inte litar på sina tester kan vara att man inte delat upp sina tester och då har ett antal integrationstester som behöver viss konfiguration innan de passerar, men vanligast är att man helt enkelt känner att testerna inte riktigt går att lita på.

Så, hur kan jag börja lita på mina tester?

För att kunna lita på mina tester, måste jag lita på min egen förmåga att skriva bra test. För att göra detta gäller det att inte tumma på vare sig struktur eller läsbarhet. Roy har ett par bra tips när det gäller namngivning.

Ha en konsekvent namngivning på dina testmetoder. Gärna enligt [metodundertest]_[scenario]_[resultat], vilket bli extra tydligt om vi jämför metoderna AddNumber_LessThanZero_ThrowException() och AddNumber().

Man måste också se till att döpa sina variabler korrekt och att undvika Magic numbers. Om vi jämför en assert av typen Assert.AreEqual(-77,statuscode) med att använda en konstant/variabel MISSING_COUNTRY=-77, märker vi hur mycket läsbarheten ökar då vi istället får Assert.AreEqual(MISSING_COUNTRY,statuscode).

Med vackra ord, eller i det här fallet KONSTANTER och metodnamn, kommer man inte långt om testet i sig är inte känns stabilt. För att undvika problem i dina tester finns ett (stort) antal saker att hålla koll på, här är några av dem.

Endast ett test per metod, har du flera tester (asserts) i en metod bör du bryta ut dem till egna tester. Detta gäller dock inte om du skall testa flera properties i ett och samma objekt.
Undvik logik i dina tester, har du ett antal if-satser som styr logik i ditt test kan du troligtvis refaktorera dem till egna tester.
Repeterbarhet, undvik saker som gör att varje test blir unikt. Använd ett statiskt datum istället för DateTime.Now och håll dig långt borta från allt vad slumptal heter.

Summering

Detta var bara en liten del av det som togs upp under sessionen, vilken allt som allt var mycket lärorik, även om det traditionella gitarrspelandet uteblev (den var trasig). Kan även passa på att rekommendera boken ”The art of unit testing” där han går igenom ämnet unit testing mer ingående.

Etiketter: ,

1 Kommentar