Testa och förbättra er reaktiva förmåga
Jag ska börja med att säga att jobba med att förbättra sin reaktiva förmåga inte på något sätt ska ersätta eller dra ner på den testning som vi gör proaktivt. Vi ska självklart fortfarande arbeta med att försöka hitta problem på ett tidigt stadie, sätta upp bra testfall på olika nivåer för att fånga problem med regression etc. Den reaktiva förmågan ska ses som ett komplement och är något som jag upplever blir allt viktigare i takt med att våra system och vår arkitektur blir alltmer komplexa och att våra arbetssätt blir mer iterativa och snabbare samtidigt som ansvar och befogenheter/möjligheter i våra team ökar.
Resan hit
När jag började min resa som testare så jobbade vi ofta mot ett (1) system som vi fick i en (1) klump som vi kunde installerade på en (1) testmiljö och som vi sedan spenderade några dagar med att testa. Kanske hade systemet något eller några externa beroenden som vi också kopplade till vårt system för att testa att integrationerna fungerade. Det var ett relativt kontrollerat och ofta arkitektur-mässigt "enkelt" system, även om systemet i sig var stort, komplext och ofta klumpigt. En klassisk monolit helt enkelt där den interna komplexiteten ofta gjorde att något gick sönder när något nytt utvecklades och lades till. Det gjorde behovet av regressionstestning stort.
Nuläget
Numera jobbar man ofta i en mikrotjänst-arkitektur där varje liten komponent eller mikrotjänst i sig ofta inte är överdrivet komplex och testningen på den nivån är relativt enkel. Komplexiteten ligger istället på systemet som en helhet när vi har kanske 100-tals små mikrotjänster som ligger och snurrar, kanske till och med i olika miljöer och i molnet. Samtidigt som vi också har externa beroenden, tredjepartssystem etc. som höjer komplexiteten och sänker testbarheten. Från att bara ha installerat en monolit på en testmiljö på en burk som kör nere i källaren så är uppsättningen för att få en komplett testmiljö extremt mycket mer komplex. För att inte tala om att få till vettig testdata som dels ska vara konsistent genom hela miljön och dels är relevant. Nya versioner av mikrotjänsterna levereras ut kontinuerligt av flertalet team och att hålla testmiljöer och sig själv uppdaterad är i stort sett omöjligt även om det så klart finns tekniska verktyg för att hjälpa oss med det. Till slut inser man att det enda vettiga sättet för att relativt snabbt se om vår ändring håller hela vägen i denna djungel av komponenter är att snabbt få ut den i den enda miljön som vi vet ska fungera, är uppdaterad och innehåller bra, kvalitativ testdata - produktion.
Testa i produktion
Testa i produktion? Är du galen? Jag förstår reaktionen, men har vi en tillräckligt hög tilltro på att våra ändringar inte kommer att skapa problem genom vårt proaktiva arbete och vi har en bra reaktiv förmåga om det skulle gå snett, så kan det vara en väg framåt. Har vi dessutom verktyg för att se till att problemen inte drabbar alla användare så är det ännu bättre. Det ska påpekas att för varje ändring ska man fundera på risk och hur kritiskt systemet eller funktionaliteten är.
Konkreta tips
Det finns massor att säga i det här ämnet men här kommer några mer eller mindre konkreta tips till hur vi kan förbättra vår reaktiva förmåga och minska risken vid kommande releaser:
- Testa och förbättra er loggning. Det som skrivs i loggarna ska vara vettiga, intressanta saker som hjälper oss när problem uppstår. Fundera på vilken information vi skulle kunna behöva i en sådan situation. Se också till att loggarna ligger på rätt lognivå i form av error, warning, info, debug, etc. Vi vill inte ha loggar som hela tiden ropar varg med en massa errors som egentligen inte är riktiga fel. När problem uppstår så finns det risk att vi inte ser skogen för alla träd och att loggarna sprutar ut information där endast någon procent är vettigt för oss.
- Sätt upp larm på situationer vi vill bevaka. Det kan vara allt från antal fel i loggarna, minneshantering, cachehantering, köer som är fulla, köer som är tomma (vilket kan vara ett tecken på att något är fel), etc. Fundera på vad som ger värde till er som team och se till att larmen kommer på ett smidigt sätt till teamet som är ansvariga för den specifika komponenten eller funktionen.
- Sätt upp dashboards med mätvärden, grafer, etc. där man kan få en överblick på hur våra komponenter och flöden mår. Samma sak där, fundera på vad som ger värde och använd era dashboards för att lära er mer om er komponent och hur den faktiskt används i produktion. Rätt uppsatt kan den ge information om användarnas beteendemönster, last och prestanda.
- Se till att alltid vara release-redo. Håll byggpipor gröna och se till att det inte ligger ändringar som inte är släppta till produktion. När vi väl snabbt behöver lösa ett problem i produktion vill vi inte få med en massa andra saker som bara har legat och väntat.
- Få ut varje ändring till produktion separat för att undvika större releaser med flera ändringar som gör det svårare att hitta rotorsaken till problem. Ha det som regel även om ändringen i sig kan ses som trivial.
- Håll komponenterna små, smidiga med ett tydligt ansvar för att dels enklare kunna hitta rotorsaken och dels få en snabbare byggpipa.
- Se till att komponenterna hålls uppdaterade med fräscha beroenden. Ibland kan lösningen på ett kritiskt problem i produktion kräva att vi behöver gå upp till den senaste versionen av ett beroende i koden. I det läget vill vi inte redan från början ligga långt efter i versioner och därmed riskera att vi i detta kritiska skede få med oss massa andra ändringar. Det skulle dels innebära förhöjd risk och dels kunna medföra att vi behöver göra ytterligare justeringar i vår kod och öka både risk och tidsåtgång för att lösa problemet.
- Lägg era testfall på rätt nivå. Ofta har vi en kombination av enhetstester och komponenttester på våra mikrotjänster. Tänk på att ju högre upp i testpyramiden desto långsammare blir testerna och därmed även byggpipan.
Med det säger jag tack, önskar er en glad lucia och hoppas att ni fick med er något från den här luckan. Hitta er balans mellan proaktivitet och reaktivitet!