Total Cost of Test Ownership (TCTO)

Geschreven door Bas Stoker

Gepubliceerd op 02 juli 2020

Het magische toverwoord bij veel salesgesprekken is TCO. Total Cost of Ownership. Van autoshowroom “Deze auto is wel wat duurder maar een stuk zuiniger” tot een nieuw ERP-pakket “Ons product kost misschien wel wat, maar u verdient dit door ons efficiëntere voorraadbeheer zo terug”.

Maar staan ontwikkelaars en testers wel eens stil bij dit toch bekende fenomeen? Ik denk het niet. Ik loop als ontwikkelaar al een tijdje mee in veel verschillende projecten, en vaak merk ik dat het aanpassen van bestaande componenten lastiger is dan nodig, doordat er ook veel testen zijn die aangepast moeten worden aan de nieuwe werkelijkheid.

De redenen hiervoor kunnen heel verschillend zijn, maar denk eens aan de volgende mogelijke oorzaken:

  •  Te veel willen testen op een te laag niveau; Moet je die helperfunctie echt direct unittesten of kan je beter de class zelf als 1 unit beschouwen? Het teveel testen van de implementatiedetails is in mijn optiek een anti-pattern. Ook al wordt dit vaak gedaan met de beste bedoelingen, zoals het per se willen behalen van die felbegeerde 100% code coverage…
  •  Te veel duplicatie van productielogica in de testopzet; ‘wiring’ van componenten met allerlei mocks simuleren die agnostisch zijn van het gebruikte framework? Vaak bieden frameworks ook goede ondersteuning voor het opzetten van een testcontext. Hierdoor laat je alle componenten met elkaar communiceren door de tool die je daarvoor in de productie-flow ook gebruikt. Natuurlijk gaat dit wel iets meer richting een integratietest, maar dat kan gezien de betere onderhoudbaarheid een prima keuze zijn.
  • Testen die initieel best waarde hadden in het ontwikkelproces, als hulpmiddel of ‘bouwsteiger’ van een ontwikkelaar, maar na een maand of twee al lang zijn afgedekt door een integratietest en eigenlijk best verwijderd hadden kunnen worden. 

De kosten

Even voor de duidelijkheid: we hebben het qua kosten nu nog niet eens over de tijd die het kost om al deze testen te draaien (dat en de latency-effecten op CI/CD-pipelines is een apart verhaal) – maar over de kosten van het onderhoud: de kostbare aandacht van een teamlid dat tijdens het maken van een aanpassing ~10 falende unittesten tegenkomt en die 1-voor-1 moet lezen, begrijpen en gaan repareren.

Gelukkig zie ik dit onderwerp steeds vaker terug op de agenda, bijvoorbeeld in deze blog van Shopify: https://engineering.shopify.com/blogs/engineering/spark-joy-by-running-fewer-tests

Het dilemma

Maar als teamlid een test verwijderen van een (oud-)collega, dat doe je ook niet zomaar. Stel nou dat de volgende fout in productie nou net door deze test was tegengehouden? Daar scoor je bepaald geen punten mee…

Van nature zijn de meeste mensen ook nog eens risico-avers. Maar stel nou dat je als organisatie de tijd die je bespaart met het onderhoud van tests met beperkte toegevoegde waarde zou stoppen in die nieuwe functie waar eindgebruikers al een jaar om vragen (en die ergens al bijna een laatste rustplaats heeft gevonden in een schier-eindeloze Jira-backlog)?

Dan heb je een heel ander verhaal en is je PO ook gelijk blij.

De oplossing

Net zoals productiecode zelf eigenlijk geen asset is maar een liability, geldt dat (des te meer) voor de afgeleide hiervan, de testset. In plaats van ons, op ons veilige eilandje, lekker bezig te houden met het verhogen van onze testcoverage van 95% naar 98%, zou het mooi zijn als we eens door de kostenbril naar onze tests zouden kijken. 

Kom je een vage of onduidelijke test tegen, overleg dan eens met een collega of deze niet gewoon overbodig is! Of voer je een review uit van een Pull-Request, vraag eens waarom die test een testopzet nodig heeft van 20 regels onnavolgbare code-gymnastiek 🙂

Agile testen doe je samen

Meer is niet altijd beter. Maar, zoals gezegd, individueel beslissen dat een test verwijderd mag worden is ook niet echt de way to go

De oplossing hiervoor kan zijn om dit gezamenlijk te doen. Bijvoorbeeld in een pair-programming sessie. Samen weet je veel meer van het systeem en deel je gelijk veel kennis binnen het team. Of introduceer de test-of-the-week, waarbij je als team elke week 1 test onder de loep neemt en samen kijkt of deze nog steeds nodig is of kan worden opgeschoond.

Lastig hier tijd voor vrij te maken? Stap dan eens in de huid van de autoverkoper en zeg eens wat vaker: “Gelet op de Total Cost of Ownership is dit belangrijk, want hierdoor kunnen we goedkoper nieuwe functies toevoegen aan onze applicatie…” en plan dan gelijk alvast een voorjaarschoonmaak in voor je testset! 

Gerelateerde artikelen