Syklomatisk kompleksitet i programvaretesting med eksempel

⚡ Smart oppsummering

Cyclomatic Complexity er en programvaremetrikk utviklet av Thomas McCabe i 1976 som teller de uavhengige banene gjennom et program. Den beregnes fra en kontrollflytgraf og gir antall testtilfeller som kreves for full grendekning.

  • 📐 To formler: V(G) = E – N + 2 fra grafen, eller V(G) = P + 1 fra antallet beslutningspunkter.
  • 🧮 Direkte betydning: Verdien er lik det maksimale antallet uavhengige stier, og dermed antall testtilfeller som trengs.
  • 🗺️ Grafgrunnlag: Noder representerer behandlingstrinn, og kanter representerer kontrollflyten mellom dem.
  • 🟢 1 til 10: Strukturert, velskrevet kode med høy testbarhet og lave vedlikeholdskostnader.
  • 🟠 21 til 40: Svært kompleks kode med lav testbarhet, hvor refaktorering vanligvis koster mindre enn testing.
  • 🛠️ verktøy: SonarQube, Visual Studio Code Målinger, radon og Lizard beregner det automatisk.

Syklomatisk kompleksitet i programvaretesting

Hva er McCabes syklomatiske kompleksitet?

Syklomatisk kompleksitet i programvaretesting er en testmåling som brukes for å måle kompleksiteten til et program. Det er et kvantitativt mål på uavhengige stier i kildekoden til et program. Syklomatisk kompleksitet kan beregnes ved å bruke kontrollflytgrafer eller med hensyn til funksjoner, moduler, metoder eller klasser i et programvareprogram.

Uavhengig bane er definert som en bane som har minst én kant som ikke har blitt krysset før i noen andre baner.

Denne metrikken ble utviklet av Thomas J. McCabe i 1976, og den er basert på en kontrollflytrepresentasjon av programmet. Kontrollflyt viser et program som en graf som består av noder og kanter.

I grafen representerer noder behandlingsoppgaver mens kanter representerer kontrollflyt mellom nodene.

McCabes syklomatiske kompleksitet

Flytgrafnotasjon for et program

Flow Graph-notasjon for et program definerer flere noder koblet gjennom kantene. Nedenfor er flytdiagrammer for utsagn som if-else, While, until og normal sekvens av flyt.

Flytgrafnotasjon for et program

Hvordan beregne syklomatisk kompleksitet

Matematisk representasjon:

Matematisk sett er det et sett med uavhengige baner gjennom grafdiagrammet. Code Programmets kompleksitet kan defineres ved hjelp av formelen –

V(G) = E - N + 2

Hvor,

E – Antall kanter

N – Antall noder

V (G) = P + 1

Hvor P = Antall predikatnoder (node ​​som inneholder betingelse)

Eksempel -

i = 0;
n=4; //N-Number of nodes present in the graph

while (i<n-1) do
j = i + 1;

while (j<n) do

if A[i]<A[j] then
swap(A[i], A[j]);

end do;
j=j+1;

end do;

Flytdiagram for dette programmet vil være

Beregn syklomatisk kompleksitet

Beregning matematisk,

  • V(G) = 9 – 7 + 2 = 4
  • V(G) = 3 + 1 = 4 (Tilstandsnoder er 1,2 og 3 noder)

Basissett, de fire uavhengige utførelsesstiene:

  • 1, 7
  • 1, 2, 6, 1, 7
  • 1, 2, 3, 4, 5, 2, 6, 1, 7
  • 1, 2, 3, 5, 2, 6, 1, 7

Egenskaper ved syklomatisk kompleksitet

Følgende er egenskapene til syklomatisk kompleksitet:

  1. V (G) er det maksimale antallet uavhengige baner i grafen
  2. V (G) >=1
  3. G vil ha én bane hvis V (G) = 1
  4. En vanlig retningslinje er å holde V(G) på 10 eller lavere for en enkelt modul.

Hvordan denne metrikken er nyttig for programvaretesting

Basis Path-testing er en av hvitboksteknikkene, og den garanterer å utføre minst én setning under testing. Den sjekker hver lineært uavhengige bane gjennom programmet, noe som betyr at Antall nødvendige testtilfeller tilsvarer programmets syklomatiske kompleksitet.

Denne beregningen er nyttig på grunn av egenskapene til syklomatisk kompleksitet (M) -

  1. M kan være antall testtilfeller for å oppnå grendekning (øvre grense)
  2. M kan være antall baner gjennom grafene. (nedre grense)

Tenk på dette eksemplet -

If (Condition 1)
Statement 1

Else
Statement 2

If (Condition 2)
Statement 3

Else
Statement 4

Syklomatisk kompleksitet for dette programmet vil være 8-7+2=3.

Siden kompleksiteten har beregnet som 3, er tre testtilfeller nødvendige for å fullføre banedekningen for eksemplet ovenfor.

Trinn som skal følges

Følgende trinn bør følges for beregning av syklomatisk kompleksitet og design av testtilfeller.

Trinn 1 – Konstruksjon av graf med noder og kanter fra koden

Trinn 2 – Identifisering av uavhengige veier

Trinn 3 – Beregning av syklomatisk kompleksitet

Trinn 4 – Design av testcaser

Når det grunnleggende settet er dannet, TESTKASSER skal skrives for å utføre alle banene.

Mer om V (G)

Syklomatisk kompleksitet kan beregnes manuelt hvis programmet er lite. Automatiserte verktøy må brukes hvis programmet er veldig komplekst da dette innebærer flere flytgrafer. Basert på kompleksitetstall kan teamet konkludere om handlingene som må tas for å måle.

Tabellen nedenfor gir en oversikt over kompleksitetstallet og den tilhørende betydningen av v (G):

kompleksitetsnummer Betydning
1 til 10

Strukturert og velskrevet kode

Høy testbarhet

Kostnad og innsats er mindre

11 til 20

Kompleks kode

Middels testbarhet

Kostnad og innsats er middels

21 til 40

Svært kompleks kode

Lav testbarhet

Kostnadene og innsatsen er høy

> 40

Ikke testbar i det hele tatt

Svært høye kostnader og innsats

Verktøy for beregning av syklomatisk kompleksitet

Mange verktøy er tilgjengelige for å bestemme kompleksiteten til applikasjonen. Noen kompleksitetsberegningsverktøy brukes for spesifikke teknologier. Kompleksiteten kan bli funnet ved antall beslutningspunkter i et program. Beslutningspunktene er if, for, for-each, while, do, catch, saksuttalelser i en kildekode.

Eksempler på verktøy er

  • OCLint – Statisk kodeanalysator for C og relaterte språk
  • SonarQube – Rapporterer syklomatisk og kognitiv kompleksitet på tvers av mer enn 25 språk
  • Visual Studio Code Målinger – Innebygd syklomatisk kompleksitetsanalyse for .NET-samlinger
  • Radon og Lizard – Kommandolinjekompleksitetsanalysatorer for Python og for henholdsvis flerspråklige prosjekter
  • Gmetrikk – Finn beregninger i Java relaterte applikasjoner

Bruk av syklomatisk kompleksitet

Syklomatisk kompleksitet kan vise seg å være svært nyttig i

  • Hjelper utviklere og testere med å bestemme uavhengige banekjøringer
  • Utviklere kan forsikre seg om at alle stiene har blitt testet minst én gang
  • Hjelper oss å fokusere mer på de avdekkede stiene
  • Forbedre kodedekningen i Engineering programvare
  • Vurder risikoen forbundet med applikasjonen eller programmet
  • Bruk av disse beregningene tidlig i syklusen reduserer mer risiko for programmet

Hvordan redusere syklomatisk kompleksitet

Et høyt kompleksitetstall er et signal, ikke en dom. Fire refaktoreringer står for mesteparten av reduksjonen som er oppnåelig i praksis.

  • Extract-metoden. Å flytte en gren til sin egen funksjon deler kompleksiteten mellom to moduler. Totalen på tvers av systemet er uendret, men hver enhet blir uavhengig testbar.
  • Erstatt en betinget kjede med et oppslag. En lang hvis-ellers-hvis-stige som tester den samme variabelen blir et kart eller en bryter, som kollapser mange beslutningspunkter til ett.
  • Bruk vaktklausuler. Tidlig retur av ugyldig input fjerner nestinget som en enkelt stor if-else-blokk oppretter, uten å endre oppførsel.
  • Erstatt kondisjonalis med polymorfisme. Der en betinget type aktiveres, fjerner det å flytte hver gren til sin egen klasse avgjørelsen fullstendig.

Før, med V(G) = 4:

if (user != null) {
    if (user.isActive()) {
        if (user.hasRole("admin")) {
            return grantAccess();
        }
    }
}
return denyAccess();

Etter, med samme oppførsel og nestingen fjernet:

if (user == null) return denyAccess();
if (!user.isActive()) return denyAccess();
if (!user.hasRole("admin")) return denyAccess();
return grantAccess();

En advarsel om metrikken. Syklomatisk kompleksitet teller avgjørelser, ikke vanskelighetsgrad. En switch-setning med tjue enkle tilfeller gir en score på 21, men er lett å lese, mens en dypt nestet blokk som gir en score på 8 kan være langt vanskeligere å forstå. Bruk tallet til å finne kandidater for gjennomgang, ikke som et mål å bli lurt på.

Spørsmål og svar

Ti eller færre per modul er den vanlige retningslinjen. Mellom 11 og 20 er koden kompleks, men håndterbar. Over 20 faller testbarheten kraftig, og over 40 anses modulen generelt som utestbar slik den er skrevet.

Begge gir samme resultat. P + 1 er raskere for manuell beregning fordi du bare teller beslutningspunkter. E – N + 2 er det verktøyene bruker, siden de allerede bygger kontrollflytgrafen.

Ikke nødvendigvis. Syklomatisk kompleksitet teller beslutninger snarere enn vanskelighetsgrad, så en flat bryter med tjue enkle tilfeller scorer høyt samtidig som den er lett å lese. Behandle tallet som en oppfordring til repetisjon.

De kombinerer det med endringsfrekvens og feilhistorikk for å rangere hvilke moduler som bærer størst risiko, og retter gjennomgang og testinnsats mot koden som har størst sannsynlighet for å mislykkes.

Ja. AI-assistenter foreslår vaktklausuler, f.eks.tracted-metoder og oppslagstabeller som reduserer antallet. Bekreft oppførselen med den eksisterende testsuiten, fordi en refaktorering som endrer logikken motvirker formålet.

Oppsummer dette innlegget med: