Intra-testning

John Carter beskrev en teknik på TDD-listan för ett tag sedan, som jag tog djupt intryck av.

Han beskriver någon sorts fattigmans Design By Contract, som i vaga ordalag går ut på att man strösslar assertions i sin kod för att beskriva antaganden.

Det Carter säger, och som jag till slut förstod, var att detta egentligen är samma sak som en assertion i ett enhetstest — bara inbäddat i koden. Vad jag inte hade skänkt så mycket eftertanke var att dessa assertions, precis som dem i enhetstester, faktiskt möjliggör säkrare refactoring.

Jag vill kalla det här för intra-testning, eftersom systemet i någon mån verifierar sig självt (jag var sugen på endo-testing, men det visade sig vara upptaget. Skit också.)

Vi kanske inte ska kasta xUnit till grisarna riktigt ännu. Förutom att beskriva antaganden är en solid test-svit också ett överlägset sätt att automatiskt köra igenom all kod som täcks av testerna i de spår som dragits upp av testfallen. Att lämna assertions i vår produktionskod ger oss fortfarande inget stöd i att driva den maskinellt.

Men jämför med hur du skulle testa en förändring utan vare sig tester eller assertions. Manuellt, eller hur? Peta och klicka lite, kolla så att allt ser rätt ut? Utan automatiserade tester är det det bästa vi har för att driva systemet, men genom att lägga till intra-testning kan vi ersätta trött okulär besiktning med automatisk evaluering av systemets tillstånd.

Jag säger inte att man bör föredra intra-testning framför enhetstestning, men jag tror att det kan användas för att göra de första penseldragen stadigare när man omarbetar otestad kod för att kunna få den under test.

Michael Feathers nämner aldrig den här tekniken i Working Effectively With Legacy Code, men den hör nog hemma tillsammans med de andra under rubriken ”How do I know that I’m not breaking anything?” som beskriver diverse sätt att bryta beroenden.

2 thoughts on “Intra-testning

  1. Joakim Karlsson skriver:

    En stor del av de tester jag skriver när jag skall refaktorisera kod går ut på att jag gör antaganden om hur saker och ting är tänkta att fungera. Jag ser en kodsnutt som behöver skrivas om, jag kikar lite på den, drar en slutsats om hur den skall fungera och skriver ett test som beskriver mitt antagande.

    Ibland har jag rätt i mitt antagande och ibland har jag fel. Har jag fel får jag i värsta fall ett test som fallerar på ett sätt jag inte väntat mig.

    Skulle jag koda in mitt antagande i produktionskoden skulle mina antaganden automatiskt bli sanna. Antar jag att en invariabel aldrig får vara 0 och lägger in en assertion som styrker detta, så får numera en invariabel aldrig vara 0 oavsett hur det fungerade innan.

    En form av Heisenbergs osäkerhetsprincip? Heisentester?

  2. Kim Gräsman skriver:

    Jag gillar det — Heisentester alltså!

    Du menar att ett nytt enhetstest påverkar bara testkörningen, medan ett nytt intra-test påverkar produktionskoden på ett sätt som vi kanske inte vill riskera?

    Mjo, det är ju sant. Men debug-assertions (som jag helt implicit avsåg ovan) kompileras ju som regel ut i releaseversionen som vi deployar, så där är risken obefintlig.

    Och som sagt, man bör bara behöva använda det så långt att man kan refaktorera koden till testbart tillstånd, sen är det dags att falla tillbaka i enhetstest-lunken igen.

    Verkar det vettigt?

Kommentera

Fyll i dina uppgifter nedan eller klicka på en ikon för att logga in:

WordPress.com Logo

Du kommenterar med ditt WordPress.com-konto. Logga ut / Ändra )

Twitter-bild

Du kommenterar med ditt Twitter-konto. Logga ut / Ändra )

Facebook-foto

Du kommenterar med ditt Facebook-konto. Logga ut / Ändra )

Google+ photo

Du kommenterar med ditt Google+-konto. Logga ut / Ändra )

Ansluter till %s