Tesztelés a Gyakorlatban - A szakértő tesztelők lapja


(Branch || Decision) ?

Elágazáslefedettség: A tesztkészlet által meghívott elágazások százalékos aránya. 100% elágazáslefedettség 100% döntési lefedettséget és 100% utasításlefedettséget jelent. || Döntési lefedettség: A tesztkészlet végrehajtása során a döntési eredmények meghívásának százalékos végrehajtási aránya. 100% döntési lefedettség 100% elágazáslefedettséget és 100% utasításlefedettséget jelent.

Ebben a cikkemben kódlefedettségekről lesz szó. A motivációt az adta, hogy nagyon kevesen tudják, hogy mi a különbség a decision és branch coverage között. Néhányan egyenesen kijelentik, nincs különbség, a kettő teljesen megegyezik, csupán szinonimák. Néhányan pedig (talán ők vannak többen), tudják, hogy ez nem teljesen igaz, de a különbséget nem tudják pontosan elmagyarázni. Nos, remélem nekik tetszeni fog a cikk.

Mi okozza a félreértést?

A félreértés több dologból fakad. Egyrészről az ISTQB-terminológia kijelenti, hogy a két fogalom szinonima. Még Advanced Level szinten is csak annyit említ pl. Rex Black: Advanced Software Testing Vol.3 könyve, hogy a két fogalmat szinonimaként kezeljük, mert csak nagyon csekély a különbség közöttük, amivel   a tananyag nem foglalkozik. Így aztán az ember tudja, hogy a kettő nem egyenlő egymással (legalábbis nem mindig), de ha megkérdezik tőle a vizsgán, akkor az a legkifizetődőbb, ha szinonimaként kezeli a két fogalmat.

A félreértés másik oka történelmi okokból fakad. Történetesen ugyanis a kódlefedettségek vizsgálatát nem csupán a hagyományos szoftvertesztelői szakma motiválta, hanem az ún. Avionics, azaz légi közlekedési, repülési szakma is. A különbség pont ebből adódik, a szoftvertesztelő szakma általában ekvivalensnek tekinti a két fogalmat, míg a repülős nem. Ezt a gordiuszi csomót pl. az ISTQB alapszintű vizsga a következőképpen oldja fel: megkérdezik, hogy 100%-os decision coverage, 100%-os branch coverage-et eredményez-e. Ez mindig igaz, függetlenül attól melyik felfogást alkalmazzuk. Így a vizsgakérdés megalkotója és a vizsgázó is megnyugodott, egyik sem hazudott.

Lássuk a különbséget!

A branch coverage ill. a decision coverage fogalmakból a coverage szót ismerjük, ez a lefedettséget jelenti, nyílván a különbség a másik két szó definíciójában rejlik. Tulajdonképpen csak egyféle lefedettség létezik, ez pedig a decision coverage, és a különbséget az adja, hogy a decision fogalmat hogyan definiálják (branchpointként vagy az ún. szó szerinti definíciót használják, ezeket később kifejtem), függetlenül attól, hogy magát a lefedettséget hogyan becézik. A probléma megértéséhez lássuk a következő példát:

 A := B or C;
 E := A and D;


Semmi különös, csak két értékadás, legalábbis a hagyományos szoftvertesztelői felfogás szerint. A repülős megközelítés azonban két decision lát! Ugyanis a jobb oldalon lévő logikai kifejezést ő decisionnek definiálja. Azért mert ez is egy önálló döntés, ami befolyásolja a lefutást, pl. akkor, ha az A vagy az E később fel lesz használva egy elágazásban. Ezzel szemben a szoftvertesztelői szakma decision coverage szempontjából ezzel a két utasítással nem foglalkozna, hiszen ezek nem ún. branchpointok, (olyan utasítások, amik befolyásolják a program futását, pl. if, case, while, stb. szerkezetek). Tehát a repülős szakma szigorúbb feltételeket szab, ő a branchpointokat plusz azokat az utasításokat vizsgálja, amik tartalmaznak logikai kifejezéseket, pl. értékadások vagy függvény paraméterek. Lássuk a pontos definícióját az ő megközelítésüknek. Mint már említettem, az ún. literal definíciót használják, ez pedig a következőképpen néz ki (DO-178B/ED-12B szabványban fellelhető). Tekintsük a következő példakódot:

 A := B or C;
 E := A and D;
 If E then…


Szó szerinti definíciók:

  • Minden utasítás a programban legalább egyszer meghívódik
  • Minden be- és kilépési pont a programmodulban legalább egyszer meghívódik
  • Minden elágazó utasítás (pl. if, case, while, for, stb.) minden ága legalább egyszer meghívódik
  • Minden nem konstans logikai kifejezés (logikai változókból és logikai operátorokból áll) kiértékelődik legalább egyszer igazra és hamisra is
  • Minden nem konstans logikai változó a logikai kifejezésben kiértékelődik legalább egyszer igazra és hamisra is
  • Minden nem konstans logikai változó a logikai kifejezésben önállóan befolyásolja a logikai kifejezés igazságértékét, ha a többi logikai változó fix

Hogy jobban érthető legyen, egy utasításlefedettséghez (statement coverage) csak az 1. szükséges. A decision coverage-hez az 2, 3, 4 szükséges. A legerősebb ún. MC/DC azaz, Modified Condition Decision Coverage-hez pedig a 2, 3, 4, 5, 6. Maradjunk a decision coverage-nél. Ahhoz, hogy elérjük a decision coverage-et a literal definíció szerint, a következő feltételeknek kell teljesülnie:

  • El kell érnünk, hogy a értékadás után A igaz legyen, ill. hamis (fent a 4. pont)
  • El kell érnünk, hogy a értékadás után E igaz legyen, ill. hamis (fent a 4. pont)
  • Az elágazásunkat is ki kell értékelnünk igazként és hamisként (fent a 3. pont)

Jól látható, hogy a 2-esből már következik a 3-as. De az 1. pontot mindenképpen ki kell elégítenünk, főleg, hogy E értéke függ A-tól. Ezzel szemben a hagyományos szoftvertesztelői megközelítéshez, ami csupán egy branchpointként definiálja a decisiont, csak ennek kell teljesülnie:

  • Az egyetlen elágazásunk (mert ebben a felfogásban csak ez számít), ami E-től függ, ki kell, hogy értékelődjön igazként ill. hamisként (fent a 3. pont)

Tehát jól láthatóan a hagyományos megközelítés sokkal gyengébb. Annál gyengébb, minél összetettebb a logikai kifejezésünk, ami pl. úgy viselkedik, mint az előző példában az E logikai változó. Most nézzük meg ugyanazt az összehasonlítást az MC/DC-re is, még meglepőbb dolgot fogunk tapasztalni. Itt ugyanis a literal definíció szerint a 2, 3, 4, 5, 6-os pontok a szükségesek, vagyis:

  • El kell, hogy érjük, hogy A kiértékelődjön igazra, ill. hamisra (4. pont)

  • Ha B igazról hamisra változik -vagy fordítva- akkor megváltozik A igazság értéke, ha C értéke fix (azaz közben nem változik, 5, 6-os pont)

  • Ha C igazról hamisra változik -vagy fordítva- akkor megváltozik A igazság értéke, ha B értéke fix (azaz közben nem változik, 5, 6-os pont)

  • El kell, hogy érjük, hogy E kiértékelődjön igazra, ill. hamisra (4. pont)

  • Ha A igazról hamisra változik -vagy fordítva- akkor megváltozik E igazság értéke, ha D értéke fix (azaz közben nem változik, 5, 6-os pont)

  • Ha D igazról hamisra változik -vagy fordítva- akkor megváltozik E igazság értéke, ha A értéke fix (azaz közben nem változik, 5, 6-os pont)

  • Az elágazásunkat, vagyis E-t is ki kell értékelnünk igazként és hamisként (fent a 3. pont)

Ezzel szemben a hagyományos szoftvertesztelői megközelítés, csak ezt követeli meg:

  • Az egyetlen elágazásunk (mert ebben a felfogásban csak ez számít), ami E-től függ ki kell, értékelődjön igazként ill. hamisként (fent a 3. pont), ill. E értéke befolyásolja az egész logikai kifejezés igazság értékét, ami önmaga (fent 5,6-os pont)

Vagyis ebben az esetben az MC/DC ekvivalens a DC-vel, amíg a szó szerinti definíció szerint nem!

Konklúzió

Persze a szó szerinti definíció alkalmazása erőforrás igényes, de egyes szabványok megkövetelik. Mindenesetre, ha valaki belebotlik ebbe a két fogalomba, remélem most már tisztábban látja a különbséget a két megközelítés között.

Források:
http://en.wikipedia.org/wiki/Code_coverage
http://www.faa.gov/aircraft/air_cert/design_approvals/air_software/cast/cast_papers/media/cast-10.pdf

Szerző:
Tóth Árpád

<< Vissza