Driftsäkerhet, tester och fel
Anders Tufvesson 16 november 2011
Hur skriver man kod som anses var driftsäker och vad är det – Är det kod med väldigt lite fel? Kod som inte behöver underhållas så ofta?
Jag reflekterar ofta om den tid som finns att lägga ner på ett kodstycke. Ofta är det så att beställarna vill ha jobbet utfört till så liten kostnad som möjligt (vilket jag förstår) och då blir det minimalt med tid på varje sak. Men ”vad kostar detta i längden?” brukar jag tänka då.
Som utvecklare har man alltid en viss tid till tester, det är så oerhört viktigt att testa det man skapat så att det uppför sig som förväntat. Man testar ofta normalfallen och några yttre fall som man kan tänka sig inträffar. Det brukar räcka väldigt långt. Men som alltid finns det massor av undantagsfall som man kanske inte räknat med och var ska man dra gränsen? Allt beror, tycker jag, på ändamålet och hur viktigt det är för kunden att systemet i alla skeden går smärtfritt.
Det är oerhört vanligt att vi skriver så kallade enhetstester till våra metoder, vilket testar att våra metoder beter sig som vi förväntar sig vid de vanligaste indatafallen. När det kommer till integrationstester så blir vi ofta mer frikostiga hur vi utför dem, här burkar det nämligen gå åt en del tid eftersom integrationstesterna är svåra att utföra. Något många beställare inte är beredda att lägga allt för mycket tid på.
När det däremot gäller acceptanstester så är beställare ofta mer benägna att lägga tid. Acceptanstestet är deras kvitto på att de fått vad de beställt men den här typen av tester testar i stort sett aldrig ytterligheterna.
Vi bygger sällan, om ens aldrig, system som är ämnade för att skydda eller rädda liv. Det gör att man kan fokusera mycket mer på att komma framåt i utvecklingen än att kontrollera för fel, vilket är viktigt i många av de branscher vi arbetar med (framförallt webb). Det här ses ofta positivt på från ett beställarhåll eftersom man erhåller något nytt hela tiden. Men å andra sidan här vill beställarna ha en hög tillgänglighet, applikationen skall vara driftsäker.
Men tillbaka till ursprungsfrågan; hur skriver vi kod som är driftsäker?
Hur konstigt det än kan låta tycker jag att det här är ett delat ansvar. Framförallt skall vi förklara varför vi vill lägga tid på de olika typerna av tester, vi är experterna, men å andra sidan måste beställare av applikationer vara medvetna om att tester får ta tid. Hur mycket vi skall testa och vad vi ska testa måste tas fram i perspektiv till verksamheten.
Det finns flera sätt att få något väldigt driftsäkert, och det vanligaste måste vara att man är många som delar på ansvaret att kontrollera att en viss del av kod utför det den skall. Och att utföra många och långa tester för att se till att den uppför sig som man förväntar sig i alla möjliga situationer.
Som jag skrivit i ett tidigare inlägg måste det finnas utrymme i en budget för underhåll av applikationer. Det gäller både webb- och desktopapplikationer. Omgivningen förändras något så oerhört, framförallt på webben där det kommer nya webbläsare och nya krav från beställaren varje dag. Men även desktopapplikationer behöver underhållas för att passa nya operativsystem och nya krav. Lägger man inte ner tid på att anpassa och underhålla applikationerna under tid kommer man tillslut till en punkt där det blir ett allt för stort jobb att göra.
Statens Järnvägar lanserade 1980, efter tio års utveckling och tester, ett system förhindra olyckor i tågtrafiken. Systemet hette, och heter fortfarande, ATC. Här fanns (och finns) det ingen tolerans för fel eller situationer som man inte räknat med. Sedan 1980 har det kommit tre versionuppdateringar av ATC men det det tog 13 år innan en första versionsuppdatering kom (1993 släpptes ATC2).
Hur kommer det sig då att ett sådant system klarar sig från större underhåll av koden?
Jag tror, utan att vara någon expert, att det handlar om två saker. Först och främst är det en väldigt statisk och sluten miljö men också att man har lagt ner otal timmar på testning av alla möjliga fall. Att man la ner tio år av utveckling och tester innan man införde det i stor skala på alla tåg är nog en av framgångssagorna. Efter 30 år med systemet är det så inkört att förarna nuförtiden helt förlitar sig på systemet, man kör som det heter på ”pipet” och litar fullt ut på att ATC-systemet varnar vid för höga hastigheter, röd signal eller systemfel. Hör man inget ”pip” är det bara att gasa på!
Men för oss som inte har ett slutet system eller kan lägga tid på tester?
Vi kanske får acceptera att vi kommer att ha fel i våra applikationer till en viss gräns och att vi måste vara beredda på att kontinuerligt lägga tid på att rätta de fel som uppkommer. När det kommer till driftsäkerheten finns det inga genvägar, och jag vet att man ibland brukar lösa prestandaproblem på webbplatser genom att låta dem starta om allt som ofta. En fräsch start löser ofta mycket konstiga tillstånd i ett system men är ingen bra utväg. I dessa fall kanske man ska fundera på om det inte är värt att lägga tid på att hitta felen och rätta dem.
Utvecklare: varför skriver ni fel över huvud taget?
Den frågan får jag ibland och den är alltid lika intressant att svara på. Det finns ingen, eller i alla fall nästan ingen, utvecklade som medvetet skriver kod som man vet är fel. Däremot finns det alltid massa undantag på in och utdata som kan ställa till det. Det värsta en utvecklare kan handskas med är indata från okända källor (som användare), för man vet aldrig hur den ser ut. Utöver detta har vi fall där data har blivit korrupt eller andra hjälpfunktioner man använder sig av får problem med att köra. Kanske är det slut på RAM-minne, slut på diskutrymme, fullt på stacken, för långsam nätverksanslutning, kommunikationsproblem med I/O, ja allt detta kan hända men kanske inte är något man kontrollerar när man ska addera två tal. Jag vet att jag överdriver lite granna nu, men i realiteten skulle vi behöva kontrollera så otal många fall för att verifiera att allt fungerar som det skall om vi ska täcka alla möjliga fel som uppkommer. Varje fall måste dessutom hanteras på olika sätt, sådant tar tid!
I bland händer det förvisso att vi skriver fel också, men det är sällan med flit. I avancerade applikationer finns det alltid möjlighet till tankevurpor.
Så slutligen så kan jag konstatera att vi skulle behöva lägga mycket tid på tester om vi vill få allt problemfritt från början, men att vi åtminstone lägger tillräckligt med tid för att hitta de värsta felen och sedan löser resten när de inträffar.
Kuriosa:
För den intresserade finns ATC i version 1, 2, 2.1 samt 2.2. De stora skillnaderna är mellan ATC1 och ATC2 där är frikostigare med att lossa en automatisk driftsbroms som ATC har slagit till vid för hög hastighet/närmande av stoppsignal om den märker att föraren försöker bromsa själv. Dessutom ändrades vad som bänder om flera hastighetangivelser tas emot, tidigare använde ATC den lägsta medan i den nya versionen den som senast togs emot. De två senaste uppdateringarna 2.1 och 2.2 syftar enbart till att lösa specifika problem. 2.1 möjliggör för systemet att ta emot körbesked via radio som ett komplement till balisier på marken. Det gör att man kan ge nya körbesked (ex. höjd hastighet) om en ex. signal längre fram slår om från rött till grönt. På så sätt kan man häva ett besked om hastighetsnedsättning innan man når nästa signalen vilket resulterar i att tåg kan köras snabbare och mer effektivt. Version 2.2 löser problem för tåg som åker över Öresunsbron och in i Danmark där man har en annan typ av ATC. Omkopplingen mellan systemen måste ske automatiskt, vid exakt rätt tillfälle, i 200km/h.
Källor:
http://techworld.idg.se/2.2524/1.160472/med-atc-systemet-gar-taget-som-pa-rals
Etiketter:acceptanstester, enhetstester, Fel, integrationstester, Testning, tidåtgång
16 november 2011 |
3 Kommentarer