Uppdaterat 2015-04-06 1.1 Systemunderhåll, kvalitetsarbete, testning
1.2 Typer av systemunderhåll: Corrective maintenance Adaptive maintenance Perfective maintenance Underhållsarbetet pågår under systemets livstid. Teknisk dokumentation och designdokumentation ett måste för att kunna orientera sig i systemets komplexitet och bedöma konsekvenserna av ens ändringar.
Corrective maintenance Rätta fel - sådant som brukar kallas för en bug. http://en.wikipedia.org/wiki/software_bug 1.3 1947
1.4 1. Identifiera problem efter att systemet har installerats och tagits i drift. T.ex. fakturans totalbelopp blir ibland fel, en knapp öppnar inte rätt formulär. 2. En felrapport skapas. (Hos vissa verksamheter: fel- och avvikelserapport - FAR). 3. Underhållspersonal o/e utvecklare rättar felet. 4. Testare utför tester för att kontrollera att felet är åtgärdat. 5. Rättelsen införs i driftsystemet (operationella systemet). Kan även avse att reparera hårdvarufel. Beroende på mjukvarans storlek kan underhållspersonal, utvecklare, programmerare och testare vara olika personer eller rent av samma person.
Adaptive maintenance 1.5 Utförs för att anpassa systemet till förändringar i omvärlden T.ex. regeringen har beslutat att differentierad moms ska införas ==> alla varorna måste märkas upp med rätt momssats, nya attribut, ändrad programkod för momshantering. T.ex. nya löneavtal mellan arbetsmarknadens parter ==> delar av lönehanteringssystemet måste programmeras om (avtalens struktur kan ändras godtyckligt och det går därför inte att förlita sig på att man bara behöver ändra värden på några attribut). förändringar av verksamhetens inriktning eller regler Ändringsbehovet beror alltså inte på att det finns fel i systemet. Ändringsbehoven går ej att förutse.
1.6 Perfective maintenance Systemet har varit i drift en tid, och det genomförs ändringar för att göra det bättre. T.ex. sättet att mata in data i ett fakturaformulär ändras för att det ska bli lättare för användaren att göra sitt jobb. T.ex. programkoden struktureras om för att det ska vara lättare att förstå vad den gör, lättare att ändra i den utan att orsaka nya fel. Detta för att underlätta framtida underhållsarbete.
Utveckling av system & program 1.7 60% - 70% av felen i programkoden uppstod innan koden ens var skriven! Viktigt att arbetet som föregår kodningen är komplett, konsistent och korrekt. Den inledande uppgiften i laborationen avser att illustrera detta.
MÅL: Tillförlitlig produkt/tjänst (god kvalitet vem bestämmer det?) 1.8 Utför vad beställaren/användarna förväntar. Stämmer med dess kravspecifikation. Aldrig felaktiga beteenden eller utdata oberoende av indata och handlingar som användaren utför. Meningsfulla och användbara beteenden i oväntade situationer. Inte tillåta att funktioner, data m.m. ändras på icke önskvärt sätt.
VAD GÖRA FÖR ATT UPPNÅ DETTA? Kvalitetssäkring (Quality Assurance) 1.9 Utvecklingsprocess som garanterar kvalitet och förhindrar uppkomst av fel. Viktiga initiativ exvis: - ISO 9000-standarden (1980-talet). - Verktyget PERFIDE i ESPRIT-projektet REQUEST (Reliability and Quality of European Software Technology): step-by-step integration (senare delen av 1980-talet). - Systemutvecklingsmodeller/-metoder (begreppet Software Engineering på NATO-konferens i Garmish 1968 vattenfallsmodeller/-metoder). Testning (felsökning, felrättning). God programmerarsed.
Några typer av kontroller inom QA 1.10 Validering. Avgör huruvida produktens funktioner är vad kunden verkligen vill ha och behöver. Bygger vi rätt produkt? Verifiering. Avgör huruvida produkten uppträder på det sätt och ger de resultat som nämns i kravspecifikationen. Bygger vi produkten på rätt sätt? Testning. Exekvera produkten i avsikt att hitta fel (för att kunna korrigera dem innan produkten tas i drift).
God programmerarsed 1.11 (många åsikter om detta, hämtat från olika källor) Överblickbar layout. Metodiskt och konsekvent uppbyggd. Lättläst och lättförståelig kod (t.ex. m.a.p. layout: lufta, indrag). Tydliga beslutsstrukturer. En sats/instruktion per rad. Inga vilda hopp, t.ex. GOTO-satser, illa motiverade uthopp ur loopar och andra styrstrukturer. Egentligen: Utnyttja språkets möjligheter till god struktur, t.ex. indelning i funktioner, de vanliga styrstrukturerna, klasser, metoder. Inkapsling, information hiding. Undvik hårdkodning av värden använd konstanter, variabler, parametrisering av externa värden.
Beskrivande namn som inte är alltför långa. Tydlighet och begriplighet, t.ex. NoOfItems eller number_of_items istf noofitems, parenteser för utvärdering av uttryck. Beskriv modulens (procedurens, metodens, klassens etc) gränssnitt och vad den ska göra. Kommentera vettigt. Undvik vitt infobrus, t.ex. att kommentera sådant som är självklarheter för en programmerare såsom hur en loop utförs. Variablenamn etc används endast till en sak. Effektivisera koden för vinster avseende exvis prestanda endast om det ger stor utdelning. 1.12 --------------------------------------------------------------------------------------------------------------------------- Vanliga engelska benämningar för "programmerarsed": programming practice programming standard coding practice coding standard ---------------------------------------------------------------------------------------------------------------------------
1.13 Exempel Från exempel_average_points.pdf. Beställarens önskan. Användaren matar in poäng på en tentamen för varje kursdeltagare, och programmet räknar ut och visar medelpoängen för tentamen. Föreslagen produkt. Ett program där respektive kursdeltagares poäng skrivs in och som sedan beräknar medelpoängen och presenterar den. Validering. Produkten tillgodoser beställarens önskan? Beställarens önskan = Vad beställaren verkligen behöver? (T.ex. kommer medelpoängen att användas på ett för verksamheten meningsfull sätt?)
1.14 Kravspecifikation: (en kompakt, förenklad variant för föreläsningsexemplet) Snabb och enkel inmatning av tentamenspoängen för alla studenterna på en kurs (max cirka 150 st). Räkna ut medelpoängen och presentera den. Kunna göras för flera kurser utan att behöva starta om programmet. Tolkning av beställarens önskan: Underförstått att det ska kunna göras på mer än en kurs, men bara en kurs åt gången. (Vanligt att behöva uppfatta och formulera sådant som är underförstått.)
1.15 också designen som uppfyller kraven: ( JSP-diagram )
Granskning 1 - granskning av designen 1.16 Förbered med att skapa en checklista med sådant som är viktigt att kontrollera i den aktuella granskningen Checklista för design ID Fråga / kriterium Kommentarer C001 Är allt begripligt? C002 Kommer algoritmen fram till en slutpunkt? C003 Stämmer strukturen med högnivåstrukturen? C004 Finns logiska fel? C005 (Högnivåstruktur: Någon form diagram som visar huvuddelarna i systemet.) Undvik att alltid använda samma checklista. Låt den bestå av två delar: - standardpunkter som används i nästan alla granskningar. - kriterier som är speciella för varje tillfälle.
Protokollet för den genomförda granskningen: 1.17 Protokoll för ganskning av JSP-diagrammet Nr Granskat Felbeskrivning KID Defektgärd Åttyp 1 Tomma rutan Tomma rutan ha innehåll? C001 1 2 Medelvärde Varifrån kommer antalet som används för att räkna ut medelpoängen? C001 2 3 JSP kommer OK C002 - X att nå ett slut 4 JSP, Högnivå 5 Avbryt?, Sluta? JSP-strukturen stämmer inte med indelningen i delsystem. Framgår inte vad som ska hända när användaren har gjort sitt val C003 2 C003 2 6 (3?) OK
Åtgärder för designen 1.18 Fyll i protokollet med åtgärderna. Vid behov förtydligande kommentarer nedanför. Protokoll för ganskning av JSP-diagrammet Nr Granskat Felbeskrivning KID Defekttyp Åtgärd 1 Tomma rutan Tomma rutan ha innehåll? C001 1 "Gör jobbet" 2 Medelvärde Varifrån kommer antalet som C001 2 Ingen 3 JSP OK C002 - - X 4 JSP, Högnivå JSP-strukturen stämmer inte 5 Avbryt? Sluta? med indelningen i delsystem. Framgår inte vad som ska hända när användaren har gjort sitt val (1. Alternativ: Ta bort rutan.) C003 2 C003 2 JSP följa används för att räkna ut medelpoängen? högnivåstrukturen Rita in. OK
Kommentar: Olämplig åtgärd för punk 2. Protokoll för granskning av JSP-diagrammet Nr Granskat Felbeskrivning KID Defekttyp Åtgärd 1 Tomma rutan Tomma rutan ha innehåll? C001 1 "Gör jobbet" 2 Medelvärde Varifrån kommer antalet som används för att räkna ut medelpoängen? C001 2 Ingen 1.19 OK Antalet skulle kunna fås fram på t.ex. något av följande sätt. A. Görs i Inmatning: En räknare som ökas med 1 för varje inmatat värde. B. Görs i Beräkning: Räkna antalet inmatade element i arrayen. C. Görs så här i programkoden (olämpligt att sprida ut beabetningen så här): Görs i Inmatning: En räknare för indexpostionen i arrayen som räknas upp för varje värde som lagras i arrayen. Görs i Beräkning: Räknarens värde ökas med 1 för att få antalet värden. Diagrammet borde visa och därmed styra hur värdet ska fås fram. ==> Beslutet om punkt 2 är inte bra pga leder till oklarhet för programmeraren och att den måste fatta ett godtyckligt beslut.
Korrigerad design (utifrån den olämpliga åtgärden om punkt 2): 1.20
public void calculateaveragepoints() throws IOException { final int ANTAL = 150; int x, i = -1, sum; String svar; int[] tal = new int[antal]; //Det 150:e elementet har index 149. BufferedReader br = new BufferedReader(...); do { // En kurs do { //Inmatning System.out.printf("Poäng följd av ENTER: "); i = i + 1; //Indexpositionen i arrayen x = Integer.parseInt( br.readline() ); //Inmatning en poäng tal[i] = x; } while (!(x == 0) i == ANTAL ); // Avbryt? sum = 0; for (int k = 0; k <= i; k++) { sum = sum + tal[k]; } System.out.print("Medelpoäng: "); System.out.format("%7.1f%n", (double)(sum/(i + 1))); System.out.printf ("Sluta? (J/N) "); svar = br.readline(); } while (!svar.equals("j")); //Sluta? } Obs, antalet räknas ut på två platser! Så går det när ej specat i designen ( Kommentarerna är utförligare i filerna med programkod.) 1.21
Granskning 2 kodens överensstämmelse med designen 1.22 Checklista för programkodens överensstämmelse med designen ID Fråga / kriterium Kommentarer C001 Går det att följa från diagrammet Spårbarhet är mycket viktigt. till koden? C002 Stämmer koden med diagrammet? Den kan göra det även om spårbarheten är dålig. C003 Svårt att förstå vad koden gör? En svårbegriplig kod medför höga underhållskostnader. C004 Finns logiska fel? Leder ofta till felaktigt beteende. En allvarlig typ av defekt.
1.23 Protokoll för ganskning av programkoden jämförd med designen (ingen testkörning) - förkortad lista Nr Granskat Felbeskrivning KID Defekt- Åtgärd OK typ 3 Separeringen Uträkning och utskrift av medelvärdet ej separata i koden. av Beräkning och Utskrift. C002 2 Separera 4 Hur antalet inmatade poäng fås fram 5 Alla möjlig poängtal går att mata in 7 Brytvillkoret för iterationen Inmatning 8 Brytvillkoret för iterationen En kurs Svårt att förstå vad (i + 1) är på programraden System.out.format... Går inte att ange 0 poäng pga att nollan tolkas som att användaren vill avbryta inmatningen. Ingen variabel som heter avbryt trots att JSP tyder på att den borde finnas Ingen variabel som heter sluta trots att JSP tyder på att den borde finnas C003 2 C004 3 C003 2 C003 2 Ny variabel för antal inmatade poäng. Annat sätt att avbryta Ny variabel: avbryt Ny variabel: sluta
Klassens namn: AveragePoints01. //ÄNDRAT FRÅN VERSION 00: // Lagt till antalinmatade. // x och sum har nu datatypen Double - ändrat på flera platser // Ändra brytvillkor i inmatningsloppen från 0 till -1. // Medelpoäng räknas ut och skrivs ut som två separata operationer. public void calculateaveragepoints() throws IOException { // Utför rutan 'Medelpoäng för kurser' i JSP-diagrammet. //Konstanter final int ANTAL = 150; //Variabler int i = -1; Double x, sum; int antalinmatade; Boolean avbryt, sluta; //NYTT String svar; Double medel; Double[] tal = new Double[ANTAL]; BufferedReader br = new BufferedReader(...); do { // En kurs 1.24
do { //Inmatning en poäng (den tomma rutan i JSP-diagrammet) System.out.printf("Poäng följd av ENTER (-1 för att avsluta): "); i = i + 1; x = Double.parseDouble( br.readline() ); tal[i] = x; avbryt = (x == -1) i == ANTAL; } while (!avbryt ); // Avbryt? antalinmatade = i + 1; // Hör till Inmatning sum = 0.0; for (int k = 0; k <= i; k++) { sum = sum + tal[k]; } System.out.print("Medelpoäng: "); medel = sum/antalinmatade; System.out.format("%7.1f%n", medel ); // Utskrift //Sluta? System.out.printf ("Sluta? (J/N) "); svar = br.readline(); sluta = svar.equals("j"); } while (!sluta); //Sluta? } 1.25
Granskning 3 testköring 1.26 Inspektion av programkodens kvalitet 1. Räknas medelvärdet ut korrekt? Skrivbordskörning av detta kodsegment. Variabelvärden skrivs in på pappret. (nästa sida...)
1.27
1.28 Man kan förstås även provköra koden och upprätta ett testprotokoll: Test Funktion Input Output Förväntad Verklig 1 Korrekt uträkning av medelvärde 2 3-1 2,5 1,33 FEL! (Den blå texten är vad som kallas för ett testfall.) Alltså är något fel med hur uträkningen går till.
Analys av felorsaken: Varvräknaren i räknas upp under det varv då användaren väljer att avbryta och visar därmed en inmatning för mycket (i får ett för högt värde). 1.29 Man bestämmer sig för att ändra koden så att variabeln i endast räknas upp, om användaren inte har matat in -1. Samma gäller för instoppningen av värdet i arrayen.
Koden inne i den innersta loopen blev så här efter korrigeringen: 1.30 Klassens namn: AveragePoints02. i = -1; do { // En kurs do { System.out.printf("Poäng följd av ENTER (-1 för att avsluta): "); } x = Integer.parseInt( br.readline() ); avbryt = (x == -1); if (!avbryt ) { i = i + 1; tal[i] = x; // Undvik att ändra avbryt från True till False. // Ändra bara om det är till True. if (i == ANTAL){ avbryt = true; } } } while (!avbryt );...
1.31 Konstruera testfall Skapa ett testfall, som demonstrerar att uträkning alltid görs rätt. En black box-test: Mata in vissa poängvärden och kontrollera att den uträknade medelpoängen är rätt. Output Test Funktion Input Förväntad Verklig 1 Korrekt uträkning av medelvärde 2 3-1 2,5 1,33 FEL! Efter korrigering av programkoden: Kod version 02. 1 Korrekt uträkning av 2 3-1 2,5 2,5 medelvärde Sluta=N 2 Korrekt uträkning av medelvärde (körs direkt efter Test 1) 8 5 10-1 7,7 (7,666 avrundat) 5,6 FEL!
Analys av felet: 1.32 För att kunna studera vad som händer: Lägg till en rad som skriver ut summan och antalet innan medelvärdet räknas ut (röd): //Summera sum = 0; for (int k = 0; k < antalinmatade; k++) { sum = sum + tal[k]; } System.out. println( sum= + sum + antal= + antalinmatade); //Medelvärde.... Kör testfallet igen: Sum = 28 och antal = 5. Ingen av dem är rätt. Ska vara 23 respektive 3. Slutsats: Felet inträffar innan medelvärdet räknas ut. Felorsak: Varvräknaren i återställs inte, innan värdena för Test 2 matas in.
Korrigera felet (klassnamn AveragePoints03) : 1.33 do { // En kurs i = -1; // Flyttad hit. } do { System.out.printf("Poäng följd av ENTER (-1 för att avsluta): "); x = Integer.parseInt( br.readline() ); avbryt = (x == -1); if (!avbryt ) { i = i + 1; tal[i] = x; if (i == ANTAL){ avbryt = true; } } } while (!avbryt );...
Testkör: 1.34 Test Funktion Input Output Förväntad Verklig 1 Korrekt uträkning av medelvärde 2 3 0 2,5 1,7 FEL! Efter korrigering av programkoden: Kod version 02 (eller hur du föredrar att göra numreringen) 1 Korrekt uträkning av medelvärde 2 3 0 Sluta=N 2,5 2,5 2 Korrekt uträkning av medelvärde (körs direkt efter Test 1) 8 5 10 7,7 (7,666 avrundat) 5,6 FEL! Efter korrigering av programkoden: Kod version 03 1 Korrekt uträkning av medelvärde 2 3-1 Sluta=N 2,5 2,5 2 Korrekt uträkning av medelvärde (körs direkt efter Test 1) 8 5 10-1 7,7 (7,666 avrundat) 7,7
----------------------------------------------------------------------------------------------------------- För att styra vad som testas kan man behöva ge vissa variabler ett visst värde under testkörningen. 1.35 I föregående exempel är det känt att det korrekta värdet för sum är 23 och för antalinmatade är det 3. Ge dem de värdena, innan uträkningen av medelvärdet görs (röd text). Då går det att se om uträkningen av medelvärdet sker korrekt förutsatt att den uträkningen ges korrekta indata. (denna teknik kan behövas i laborationen.) //Summera sum = 0; for (int k = 0; k < antalinmatade; k++) { sum = sum + tal[k]; } sum = 23; antalinmatade = 3; //Medelvärde. Sedan gäller det att komma ihåg att ta bort dessa temporära tilldelningar. -----------------------------------------------------------------------------------------------------------
1.36 2. Avbryts loopen för Inmatning korrekt, när arrayen innehåller det maximalla antalet element? 3. Det ska inte gå att mata in negativa poäng. Osv tills allt är korrekt. ---------------------------------------------------------------------------------------------------------- Det fullständiga exemplet finns i exempel_average_points.pdf. ----------------------------------------------------------------------------------------------------------
Förresten, lade du märke till att designern tidigt skrev kurs i stället för tentamen? 1.37
1.38 Principer, riktlinjer, praxis Nackdelar med kodning och testkörning direkt: (Vanligt att man frestas göra så) Endast ett fel upptäcks och kan rättas till per testkörning ==> - Tar lång tid att få ett felfritt program. Tid som kunde använts bättre. - Ev belastas maskiner och annan utrustning i onödan.
1.39 Bättre med inspektion av koden innan körning: Skrivbordskörning enskilt och redovisning med inspektionsmöte i grupp. Enda syftet och resultatet: Konstatera förekomst av fel. Programmeraren rättar efter mötet. ==> + Många fel upptäcks på en gång. + Sparar kodningstid, maskintid etc. + Felfriare programvara snabbare. (Jfr. agila iterativa metoder.)
Två synsätt: Vita lådor och svarta lådor 1.40
1.41
1.42
1.43 Exempel Ekvivalensklasser Domän: heltal -100 ==> +100 Två testklasser: - positiva heltal (en test) - negativa heltal (en test) Gränsvärdesanalys Test av -100: -101, -100 Test av -1: -1, 0 Test av +100: +101, +100 Test av +1: +1, (0 redan testad ovan) Specialvärden <ENTER> 0 Null (allt som för systemet motsvarar tomma mängden)
Vanliga och viktiga typer av tester på systemnivå Systemtestning. Integrationstestning. Regressionstestning. Acceptanstestning. 1.44 Planera testningen redan under designen. Se till att från början bygga in testbarhet, annars är risken stor för att testningen blir bristfällig.
1.45
1.46
1.47
1.48
1.49
Automatiserad testning 1.50 Sparar tid, resurser och pengar. Tillförlitligare utförande av testfall än människor och dessutom upprepbart. Avlastar människor tråkigt arbete. Annan än testkonstruktören kan utföra testerna, dvs starta exekveringen av de automatiska testfallen. Regressionstestning används med fördel.