Kodtäckning - Code coverage
| Programkörning |
|---|
| Allmänna begrepp |
| Typer av kod |
| Sammanställningsstrategier |
| Anmärkningsvärda driftstider |
|
| Anmärkningsvärda kompilatorer och verktygskedjor |
|
Inom datavetenskap är testtäckning ett mått som används för att beskriva i vilken grad källkoden för ett program körs när en viss testsvit körs. Ett program med hög testtäckning, mätt i procent, har utfört mer av sin källkod under testning, vilket tyder på att det har en lägre chans att innehålla oupptäckta programvarufel jämfört med ett program med låg testtäckning. Många olika mätvärden kan användas för att beräkna testtäckningen. några av de mest grundläggande är andelen program subrutiner och andelen program uttalanden kallas vid körning av testsvit.
Testtäckning var bland de första metoderna som uppfanns för systematisk programvarutestning . Den första publicerade referensen var av Miller och Maloney i ACM Communications 1963.
Täckningskriterier
För att mäta vilken procentandel kod som har utövats av en testsvit används ett eller flera täckningskriterier . Täckningskriterier definieras vanligtvis som regler eller krav som en testsvit behöver uppfylla.
Grundläggande täckningskriterier
Det finns ett antal täckningskriterier, de viktigaste är:
- Funktionstäckning - har varje funktion (eller underrutin ) i programmet anropats?
- Uttalande täckning - har varje uttalande i programmet utförts?
- Kantskydd - har varje kant i kontrollflödesdiagrammet körts?
- Branch täckning - har varje gren (även kallad DD-path ) för varje kontrollstruktur (till exempel i om och fall uttalanden ) utförts? Till exempel, med ett if- uttalande, har både de sanna och falska grenarna utförts? Detta är en delmängd av kanttäckning.
- Villkorstäckning (eller predikattäckning) - har varje booleskt subuttryck utvärderats till sant och falskt?
Tänk till exempel på följande C-funktion:
int foo (int x, int y)
{
int z = 0;
if ((x > 0) && (y > 0))
{
z = x;
}
return z;
}
Antag att den här funktionen är en del av ett större program och det här programmet kördes med någon testsvit.
- Om 'foo' under denna exekveringsfunktion anropades minst en gång, är funktionstäckningen för denna funktion nöjd.
-
Uttalningstäckning för denna funktion kommer att vara tillfredsställd om den kallades t.ex. som
foo(1,1), som i detta fall, varje rad i funktionen körs inklusivez = x;. - Tester som anropar
foo(1,1)ochfoo(0,1)kommer att tillfredsställa filialtäckning eftersom i det första fallet är bådaifvillkoren uppfyllda ochz = x;exekverade, medan i det andra fallet är det första villkoret(x>0)inte uppfyllt, vilket förhindrar körningz = x;. -
Villkorstäckning kan uppfyllas med tester som ringer
foo(1,0)ochfoo(0,1). Dessa är nödvändiga eftersom det i de första fallen(x>0)utvärderas tilltrue, medan det i det andra utvärderasfalse. Samtidigt gör det första fallet(y>0)false, medan det andra gör dettrue.
Villkorstäckning innebär inte nödvändigtvis filialtäckning. Tänk till exempel på följande fragment av kod:
if a and b then
Villkorstäckningen kan uppfyllas genom två tester:
-
a=true,b=false -
a=false,b=true
Emellertid uppfyller denna uppsättning tester inte filialtäckningen eftersom inget av fallen faller ifvillkoret.
Felinsprutning kan vara nödvändigt för att säkerställa att alla förhållanden och grenar för undantagshanteringskoden har tillräcklig täckning under testningen.
Ändrat tillstånd / beslutstäckning
En kombination av funktionstäckning och filialtäckning kallas ibland också beslutstäckning . Detta kriterium kräver att varje in- och utgångspunkt i programmet har åberopats minst en gång, och varje beslut i programmet har tagit på sig alla möjliga resultat minst en gång. I detta sammanhang är beslutet ett booleskt uttryck som består av villkor och noll eller fler booleska operatorer. Denna definition är inte densamma som filialtäckning, men vissa använder termen beslutstäckning som en synonym för filialtäckning .
Villkor / beslutstäckning kräver att både besluts- och villkorstäckning är uppfyllda. För säkerhetskritiska applikationer (t.ex. för flygteknikprogram) krävs det dock ofta att modifierat tillstånd / beslutstäckning (MC / DC) är uppfyllt. Detta kriterium utökar villkor / beslutskriterier med krav på att varje villkor ska påverka beslutets resultat oberoende. Tänk till exempel på följande kod:
if (a or b) and c then
Villkor / beslutskriterier kommer att uppfyllas med följande uppsättning tester:
- a = sant, b = sant, c = sant
- a = falskt, b = falskt, c = falskt
Ovanstående testuppsättningar uppfyller emellertid inte modifierat villkor / beslutstäckning, eftersom värdet på 'b' i det första testet och i det andra testet inte skulle påverka resultatet av 'c'. Så, följande testuppsättning behövs för att tillfredsställa MC / DC:
- a = false, b = true, c = false
- a = falskt, b = sant , c = sant
- a = false , b = false , c = true
- a = sant , b = falskt, c = sant
Flera villkor täckning
Detta kriterium kräver att alla kombinationer av förhållanden i varje beslut testas. Till exempel kommer kodfragmentet från föregående avsnitt att kräva åtta tester:
- a = falskt, b = falskt, c = falskt
- a = false, b = false, c = true
- a = false, b = true, c = false
- a = falskt, b = sant, c = sant
- a = true, b = false, c = false
- a = sant, b = falskt, c = sant
- a = sant, b = sant, c = falskt
- a = sant, b = sant, c = sant
Parametervärde täckning
Parametervärdetäckning (PVC) kräver att i en metod som tar parametrar ska alla vanliga värden för sådana parametrar beaktas. Tanken är att alla vanliga möjliga värden för en parameter testas. Till exempel är vanliga värden för en sträng: 1) null, 2) tom, 3) mellanslag (mellanslag, flikar, ny rad), 4) giltig sträng, 5) ogiltig sträng, 6) enkelbytessträng, 7) dubbel- byte-sträng. Det kan också vara lämpligt att använda mycket långa strängar. Underlåtenhet att testa varje möjligt parametervärde kan leda till ett fel. Att testa endast en av dessa kan resultera i 100% kodtäckning eftersom varje rad täcks, men eftersom endast ett av sju alternativ testas finns det bara 14,2% PVC.
Andra täckningskriterier
Det finns ytterligare täckningskriterier som används mindre ofta:
- Linjär kodsekvens och hopp (LCSAJ) -täckning aka JJ-Path-täckning - har alla LCSAJ / JJ-banor utförts?
- Bantäckning - Har alla möjliga rutter genom en viss del av koden körts?
- In- / utgångstäckning - Har alla möjliga samtal och återvändande av funktionen utförts?
- Slingtäckning - Har alla möjliga slingor utförts noll gånger, en gång och mer än en gång?
- Statlig täckning - Har varje stat i en maskin med slutligt tillstånd nåtts och utforskats?
- Dataflödetäckning - Har varje variabeldefinition och dess användning uppnåtts och undersökts?
Säkerhetskritiska eller pålitliga applikationer krävs ofta för att visa 100% av någon form av testtäckning. Till exempel kräver standarden ECSS -E-ST-40C 100% uttalande och beslutstäckning för två av fyra olika kritiska nivåer; för de andra är måltäckningsvärdena upp till förhandlingar mellan leverantör och kund. Att fastställa specifika målvärden - och i synnerhet 100% - har dock kritiserats av utövare av olika skäl (jfr.) Martin Fowler skriver: "Jag skulle vara misstänksam mot allt som 100% - det skulle lukta av någon som skrev tester till göra täckningsnumren nöjda men inte tänka på vad de gör ".
Några av täckningskriterierna ovan är kopplade. Till exempel innebär vägtäckning beslut, uttalande och in- och utresa. Beslutstäckning innebär uttalandestäckning, eftersom varje uttalande är en del av en filial.
Fullständig täckning av den typ som beskrivs ovan är vanligtvis opraktisk eller omöjlig. Varje modul med en följd av beslut i den kan ha upp till banor inom den; loopkonstruktioner kan resultera i ett oändligt antal banor. Många vägar kan också vara omöjliga genom att det inte finns någon ingång till det testade programmet som kan orsaka att den specifika sökvägen körs. En algoritm för allmänt ändamål för att identifiera omöjliga vägar har dock visat sig vara omöjlig (en sådan algoritm kan användas för att lösa stoppproblemet ). Grundvägstestning är till exempel en metod för att uppnå fullständig filialtäckning utan att uppnå fullständig bantäckning.
Metoder för praktisk vägtäckningstestning försöker istället identifiera klasser av kodvägar som skiljer sig endast i antalet loopkörningar, och för att uppnå "basväg" -täckning måste testaren täcka alla banklasser.
I praktiken
Målprogramvaran är byggd med specialalternativ eller bibliotek och körs under en kontrollerad miljö för att mappa varje utförd funktion till funktionspunkterna i källkoden. Detta gör det möjligt att testa delar av målprogramvaran som sällan eller aldrig nås under normala förhållanden, och hjälper till att försäkra att de viktigaste förhållandena (funktionspunkter) har testats. Den resulterande produktionen analyseras sedan för att se vilka kodområden som inte har utövats och testerna uppdateras för att inkludera dessa områden efter behov. I kombination med andra testtäckningsmetoder är målet att utveckla en noggrann, men ändå hanterbar uppsättning regressionstest.
Vid implementering av testtäckningspolicyer inom en mjukvaruutvecklingsmiljö måste man överväga följande:
- Vad är täckningskrav för slutproduktcertifiering och i så fall vilken testtäckning krävs? Den typiska nivån på noggrannhet är följande: Statement, Branch / Decision, Modified Condition / Decision Coverage (MC / DC), LCSAJ ( Linear Code Sequence and Jump )
- Kommer täckning att mätas mot tester som verifierar de krav som ställs på systemet som testas ( DO-178B )?
- Är objektkoden genererad direkt spårbar till källkodsuttalanden? Vissa certifieringar (dvs. DO-178B nivå A) kräver täckning på monteringsnivå om detta inte är fallet: "Därefter bör ytterligare verifiering utföras på objektkoden för att fastställa riktigheten hos sådana genererade kodsekvenser" ( DO-178B ) punkt 6.4.4.2.
Programvaruförfattare kan titta på testtäckningsresultat för att ta fram ytterligare tester och inmatnings- eller konfigurationsuppsättningar för att öka täckningen över viktiga funktioner. Två vanliga former av testtäckning är uttalande (eller linje) täckning och gren (eller kant) täckning. Linjetäckningsrapporter om körningens fotavtryck för testning av vilka kodrader som kördes för att slutföra testet. Edge-täckning rapporterar vilka filialer eller kodbeslutspunkter som kördes för att slutföra testet. De rapporterar båda ett täckningsvärde, mätt i procent. Betydelsen av detta beror på vilken eller vilka täckningsformer som har använts, eftersom 67% filialtäckning är mer omfattande än 67% täckning.
I allmänhet åstadkommer testtäckningsverktyg beräkning och loggning utöver det faktiska programmet och därmed saktar ner applikationen, så vanligtvis görs denna analys inte i produktionen. Som man kan förvänta sig finns det klasser av programvara som inte kan genomföras med täckningstester, även om en viss täckningskartläggning kan approximeras genom analys snarare än direkt testning.
Det finns också några slags fel som påverkas av sådana verktyg. I synnerhet kan vissa tävlingsförhållanden eller liknande realtidskänsliga operationer maskeras när de körs under testmiljöer; men omvänt kan vissa av dessa defekter bli lättare att hitta som ett resultat av den extra omkostnaden för testkoden.
De flesta professionella programutvecklare använder C1- och C2-täckning. C1 står för uttalande täckning och C2 för gren eller täckning. Med en kombination av C1 och C2 är det möjligt att täcka de flesta uttalanden i en kodbas. Uttalande täckning skulle också täcka funktionstäckning med in- och utgång, slinga, väg, tillståndsflöde, kontrollflöde och dataflödes täckning. Med dessa metoder är det möjligt att uppnå nästan 100% kodtäckning i de flesta programvaruprojekt.
Användning inom industrin
Testtäckning är ett övervägande i säkerhetscertifieringen av flygteknisk utrustning. Riktlinjerna enligt vilka flygteknik är certifierade av Federal Aviation Administration (FAA) är dokumenterade i DO-178B och DO-178C .
Testtäckning är också ett krav i del 6 i bilsäkerhetsstandarden ISO 26262 Road Vehicles - Functional Safety .
Se även
- Cyklomatisk komplexitet
- Intelligent verifiering
- Linjär kodsekvens och hopp
- Ändrat tillstånd / beslutstäckning
- Mutationstestning
- Regressionstestning
- Programvarumätvärde
- Statisk kodanalys
- Vitlåda testning
- Verktyg för Java-kodtäckning