Download as pdf or txt
Download as pdf or txt
You are on page 1of 82

Eötvös Loránd Tudományegyetem

Informatikai Kar
Komputeralgebra Tanszék

Szoftvertesztelés a gyakorlatban
Horváth László

Témavezetı: Dr. Kovács Attila

Támogatta: GVOP - 3.2.2-2004-07-0005/3.0 ELTE IKKK

Budapest
2007.
Tartalomjegyzék

Köszönetnyilvánítás....................................................................................................................4
1. Elıszó......................................................................................................................................5
2. Bevezetés, alapfogalmak ........................................................................................................7
2. 1. A hibák típusai: mentális hiba(error), programozói hiba(fault), hibás mőködés(failure) . 8
2. 2. Teszteset ..................................................................................................................................... 9
2. 3. A program megbízhatósága...................................................................................................... 9
2. 4. Tesztelési alapelvek ................................................................................................................. 10
2. 5. Ki teszteljen?............................................................................................................................ 11
2. 6. Hibák típusai............................................................................................................................ 11
2. 7. A tesztek osztályozása ............................................................................................................. 12
2. 8. A tesztelés szintjei, tevékenységek ......................................................................................... 14
3. Funkcionális tesztelés ..........................................................................................................16
3. 1. Példák ....................................................................................................................................... 16
3. 1. 1. Háromszög probléma .......................................................................................................................16
3. 1. 2. A „NextDate” probléma ...................................................................................................................17
3. 2. Ekvivalencia-osztályozás ........................................................................................................ 18
3. 2. 1. Irányvonalak az osztályozáshoz .......................................................................................................18
3. 2. 2. Gyenge ekvivalencia-osztály tesztelés .............................................................................................19
3. 2. 3. Erıs ekvivalencia-osztály tesztelés ..................................................................................................20
3. 2. 4. Gyenge robusztus ekvivalencia-osztály tesztelés .............................................................................21
3. 2. 5. Erıs robusztus ekvivalencia-osztályozás..........................................................................................22
3. 2. 6. Ekvivalencia-osztály tesztesetek a háromszög problémára ..............................................................23
3. 3 Határérték tesztelés.................................................................................................................. 26
3. 3. 1 Határérték analízis.............................................................................................................................26
3. 3. 2. Robusztusság-teszteléss....................................................................................................................29
3. 3. 3. „Legrosszabb eset” tesztelés.............................................................................................................30
3. 3. 4. Tesztelés speciális értékekkel...........................................................................................................31
3. 3. 5. Példák...............................................................................................................................................32
3. 4. Ok-okozat gráfok és a döntési tábla ...................................................................................... 35
3. 4. 1. Ok-okozat gráfok..............................................................................................................................35
3. 4. 2. Döntési tábla.....................................................................................................................................36
3. 4. 3. Példa az ok-okozat gráfok és a döntési táblák együttes használatára ...............................................37
3. 5. A funkcionális tesztelés áttekintése....................................................................................... 39
3. 5. 1. Mit használjunk? ..............................................................................................................................39
4. Strukturális tesztelés ............................................................................................................42
4. 1. Útvonal tesztelés ...................................................................................................................... 42
4. 1. 1. DD - utak..........................................................................................................................................45
4. 2. Lefedettség metrikák............................................................................................................... 46
4. 2. 1. Metrika alapú tesztelés .....................................................................................................................47
4. 2. 2. Teszt lefedettség elemzık.................................................................................................................50
4. 3. Bázis útvonaltesztelés.............................................................................................................. 50
4. 3. 1. McCabe bázis útvonaltesztelése .......................................................................................................51
4. 4. Adatáram alapú tesztelés........................................................................................................ 54

2
4. 5. A strukturális tesztelés áttekintése ........................................................................................ 58
5. A Grafikus felhasználói interfész tesztelése ........................................................................60
5. 1. A grafikus felhasználói interfész (GUI) sajátosságai ........................................................... 60
5. 2. Néhány nehézség a teszteléssel kapcsolatban........................................................................ 61
5. 3. Tesztelési stratégia................................................................................................................... 64
5. 3. 1. Alapelvek .........................................................................................................................................64
5. 3. 2. A hibák típusai .................................................................................................................................65
5. 4. A tesztelés típusai .................................................................................................................... 66
5. 5. A tesztelés automatizálása ...................................................................................................... 69
5. 6. A felhasználói felület tervezése a könnyebb tesztelhetıség érdekében............................... 71
6. Objektumorientált tesztelés ..................................................................................................73
6. 1. Teszttervezés............................................................................................................................ 73
6. 1. 1. Objektumosztály tesztelése ..............................................................................................................74
6. 1. 2. Objektumintegráció ..........................................................................................................................76
7. Tesztelı eszközök..................................................................................................................78
8. Összefoglalás ........................................................................................................................81
Irodalomjegyzék .......................................................................................................................82

3
Köszönetnyilvánítás

Ezúton szeretnék köszönetet mondani mindazoknak, akik hozzájárultak a


diplomamunkám elkészítéséhez:

Konzulensemnek, Dr. Kovács Attilának, aki tanácsaival, véleményével és lelkes


hozzáállásával segített a diplomamunka témájának kiválasztásában és a szükséges
szakirodalom felkutatásában.

Családomnak és barátaimnak a támogatásért és legfıképp Édesanyámnak az


áldozatvállalásért, amellyel lehetıvé tette számomra egyetemi tanulmányaim elvégzését.

4
Horváth László Szoftvertesztelés a gyakorlatban

1. Elıszó

Napjainkban az informatikai projektek keretében elkészített szoftverrendszerek egyre


nagyobb méreteket öltenek, a megoldandó feladatok bonyolultsága is egyre csak nı,
miközben a határidık rövidülnek. Mind több és több területen adjuk át mindennapi
életünkben az irányítást a gépeknek, még olyan helyeken is, ahol a helytelen mőködés
emberek biztonságát veszélyezteti, esetleg jelentıs vagyoni károkat okozhat, mint például a
robotpilóták, holdjárók szoftverei, harcászati irányító rendszerek. Éppen ezért nagyon fontos,
hogy minden termék esetében biztosítva legyen a megfelelı mőködés. Ennek elérésére szolgál
a tesztelés. A kritikus rendszerek tesztelésénél különálló csapatok készítik a komponensek
számára a teszteket. A legtöbb esetben azonban a tesztelés intuitív folyamat, ahol nincs idı a
szoftverrendszer minden összetevıjérıl részletes specifikációt írni. Inkább a fontosabb
rendszerkomponensek interfészeit specifikálják, és egymástól független programozók és
programozó csoportok vállalják a felelısséget a tervezésért, fejlesztésért és a komponensek
teszteléséért. A fejlesztıknek biztosítaniuk kell, hogy az általuk készített szoftverrendszer
megfelel az elvárt minıségi követelményeknek.
A tesztelés éppen ezért egy nagyon fontos és kritikus része a szoftverfejlesztésnek, amitıl
nagyban függ az elıállított termék minısége és megbízhatósága. Az újabb szoftverfejlesztési
modellekben ez a folyamat egyre jelentısebbé válik, egyre nagyobb részét szánják rá a
rendelkezésre álló erıforrásoknak. A tesztelés nemcsak a hibák detektálására korlátozódik,
hanem nagyban hozzájárul a megfelelı mőködéshez és segíti a funkcionális és nem
funkcionális jellemzık változásainak követését is. A teszteléssel kapcsolatos tevékenységek
keretbe foglalják a szoftverfejlesztés folyamatát, amelyek már a követelményspecifikáció
során elkezdıdnek a stratégia megtervezésével. Ezek után végigkísérik a szoftver teljes
életciklusát, a különbözı fejlesztési lépéseket a kódolástól, ahol a teszteseteket futtatjuk,
egészen az üzembe helyezésig, amikor a felhasználó által jelentett hibákat is kezeljük.
Azt azonban nem szabad elfelejteni, hogy a tesztelés nem egyfajta „varázspálca”, ami
garantálja a magas minıségő szoftverek elıállítását. A tesztelés csak a hibák jelenlétét észleli,
de nem tudja igazolni azok hiányát. Sıt mi több, lehetetlen egy szoftvert teljes alapossággal
tesztelni, mert a lehetséges inputok száma túl nagy, sok a lehetséges bemeneti út és nehéz a
specifikáció, valamint a tervezés eredményét tesztelni. További jelentıs problémát vet fel a
terület kutatói számára a megfelelı tesztesetek kiválasztásának automatizálása.

5
Horváth László Szoftvertesztelés a gyakorlatban

A szoftvertesztelés velejárója a korlátok jelenléte. Mára mégis számos, a gyakorlatban is


használt elmélet és elgondolás született, hogyan lehetne mind jobbá, gyorsabbá és
hatékonyabbá tenni. A diplomamunka célja, a gyakorlatban alkalmazott eljárások bemutatása
a funkcionális és strukturális tesztelés eszközeitıl, a felhasználói felület tesztelését szolgáló
eljárásokon át, egészen az objektumorientált rendszerek tesztelésének sajátosságáig. A
dolgozat elején bevezetünk néhány alapfogalmat, amelyekre a késıbbiekben szükség lesz,
majd tisztázzuk, milyen típusai vannak a tesztelésnek. Definiáljuk a különbözı tesztszintek
fogalmát és ismertetünk néhány tesztelési technikát a funkcionális és strukturális tesztelés
témakörébıl.

6
Horváth László Szoftvertesztelés a gyakorlatban

2. Bevezetés, alapfogalmak

Amint azt késıbb látni fogjuk rengeteg tesztelési stratégia, eljárás létezik, azonban mind
egyetlen célt szolgálnak: növelni a bizalmat a szoftver megfelelı mőködésével kapcsolatban.
Ezen cél érdekében, a szoftver egyes részei különbözı paraméterekkel és objektumokkal
kerülnek végrehajtásra, tovább növelve a bizalmat azáltal, hogy felfedik a felhasználói
követelményektıl való eltérést. Ily módon javítható a biztonság, a teljesítmény, vagyis az
úgynevezett nem funkcionális jellemzık. Ahhoz, hogy minden célt kiszolgáljunk, különbözı
stratégiákat vethetünk be a tesztelés során. Általában a tesztelési stratégiákat két nagy
csoportba szokás sorolni:
1. Statikus elemzés technikája, ahol a statikus szó azt jelzi, hogy ezek a módszerek nem
foglalják magukban a rendszer végrehajtását. A statikus technikák a teljes
életciklusban alkalmazhatóak, különbözı célok érdekében, mint amilyen az
implementáció és a követelmények közötti megfelelés vizsgálata, vagy a kódolási
hibák felderítése.
2. A másik csoport a dinamikus elemzési technikáké, amelyek alkalmazása során a
tesztelı a gyakorlatban használja a szoftvert a hibák felfedése érdekében. Ezen
eljárások segítségével a program viselkedésének, és minıségének jellemzıi szintén
megfigyelhetık.
A statikus és dinamikus technikák egymást kiegészítik. Az elızı szolgáltatja az általános
jellemzıket és eredményeket, amik azonban nem elég pontosak. Dinamikus technikák
alkalmazásával sokkal pontosabb adatokat kaphatunk, de ezek csak a végrehajtásra
korlátozódnak. A dolgozatban általában dinamikus technikákkal foglalkozunk.
Vannak bizonyos matematikai igazságok, amelyeket a tesztelés során szem elıtt kell
tartanunk. A legfontosabb, hogy egy kiterjedt és alapos tesztelés után a szoftver még mindig
tartalmazhat hibákat. Amint azt Dijkstra harminc évvel ezelıtt megállapította, a tesztelés
sosem bizonyítja a hibamentességet, legfeljebb felfedi a hibák jelenlétét, hibás mőködés
elıidézésével. Az elmúlt évtizedekben, vizsgálatok és gyakorlati tapasztalatok sokaságának
köszönhetıen sok új információra tettünk szert a programok futtatásával kapcsolatban, és sok
új eszköz segíti a tesztelést. Egyre világosabban látszik, hogy csak további gyakorlati
megfigyelések növelhetik a tesztelés érettségének szintjét.

7
Horváth László Szoftvertesztelés a gyakorlatban

Éppen ezért a tesztelés egy mőszaki tudományként fogható fel, ami a gyakorlat alapján
von le következtetéseket, jelenlegi adatokból következtet a jövıre vonatkozóan, a tesztelık
korábbi tapasztalatai alapján. A szoftverek tesztelése a program viselkedésének vizsgálatát
jelenti, az elvárt viselkedést szem elıtt tartva, a tesztesetek véges készletén, megfelelıen
kiválasztva ezeket, az általában végtelen végrehajtási tartományból. Ez a rövid meghatározás
magában foglalja a tesztelés egyik legnagyobb problémáját, miszerint a program csak egy
véges, kiválasztott tesztkészleten hajtható végre a tesztelés során. Találnunk kell tehát egy
olyan eljárást, ami megfelelı feltételek mentén ideális teszteseteket választ ki. A tesztelıknek
elıvigyázatosnak kell lenniük a kiválasztási technika meghatározása során, hiszen a
különbözı tesztkészletek nagyon eltérı hatékonysághoz vezethetnek. Az „elvárt” szó mutatja,
hogy a program végrehajtása során tapasztalt mőködés elfogadható, vagy sem.

2. 1. A hibák típusai: mentális hiba (error), programozói hiba (fault), hibás


mőködés (failure)

Ahhoz, hogy a tesztelés minden oldalát megismerjük fontos, hogy tisztázzuk a


különbséget a következı három fogalom között: error, fault, failure. Habár szoros
kapcsolatban állnak egymással, van néhány alapvetı különbség közöttük.
A failure egy program esetében valamely elvárt képesség hiányának beigazolódása, azaz a
rendszer hibás mőködésének igazolása hibás kimeneti értékekkel, abnormális befejezıdéssel,
vagy végtelen végrehajtási idıvel, memóriahasználattal.
A failure oka egy hibás, vagy hiányos kódrészlet, amit fault-nak nevezünk. A fault hosszú
idın keresztül felfedetlen maradhat (okozhatja mentális hiba vagy figyelmetlenség), amíg
néhány esemény ki nem váltja azt. Ha ez bekövetkezik, a program egy közbülsı, bizonytalan
állapotba kerül, majd ez szétterjedve az outputon keresztül failure-hez vezet. A fault
alapvetıen kétféle lehet. Az elsı eset, amikor a tervezı, vagy éppen a programozó valami
olyasmit visz a rendszerbe, ami nem kellene, hogy benne legyen, és ez okoz hibát. A második
eset ennek az ellentéte, vagyis kifelejtenek valamit a rendszerbıl. A failure bekövetkezése a
következı lánccal ábrázolható:
error → fault →failure

Ez a sorozat rekurzívan iterálható, egy errort más rendszerek failure-je is kiválthat.

8
Horváth László Szoftvertesztelés a gyakorlatban

A tesztelés minden esetben a failure-t fedi fel és visszakövetés szükséges a fault


meghatározásához, ami ezt okozta. Egy fault hatása bizonytalan és nehéz elıre megjósolni,
mert nincsenek precíz kritériumok és módszerek, amelyek egy felfedett failure okát
meghatározzák.

2. 2. Teszteset

A teszteset egy (I, S, O) rendezett hármas. Az I a bemeneti értékre utal, az O pedig az


outputot jelöli. Az S nem más, mint a rendszer egy környezete, amiben a tesztet végre akarjuk
hajtani. A környezet meghatározása során törekedni kell arra, hogy a késıbbi mőködési
környezetet próbáljuk minél pontosabban lemásolni, szimulálni. A tesztelés során a rendszer
teszteseteken történı végrehajtásával próbáljuk felfedni a hibákat, illetve bemutatni a helyes
mőködést.

2. 3. A program megbízhatósága

Sajnos elkerülhetetlen, hogy néhány fault felfedetlen maradjon a tesztelés és nyomkövetés


(debugolás) során. Egy ilyen fault azonban eltérı mértékő zavart okozhat a rendszer
mőködésében. Minél gyakrabban következik be hibás mőködés, annál több kár érheti a
végfelhasználót a szoftver használata során. A termék megbízhatósága tehát egy fontos
mérıszám, amelynek segítségével megállapítható, hogy a termék készen áll-e a kibocsátásra.
Szigorúan véve a szoftver megbízhatósága egy olyan becslés, ami méri, hogy a szoftver
meddig képes hiba nélkül mőködni egy elıre meghatározott környezetben. Ily módon a
szoftver megbízhatóságának mértéke nagyban függ attól, hogy a végfelhasználó milyen
gyakran hajt végre failure-t kiváltó feladatokat.
A megbízhatóság becslését a szoftver tesztelése során lehet elvégezni. A megbízhatóság
fogalma szorosan kötıdik egy megadott környezethez. A teszteket egy olyan kitőntetett input
halmazon kell végrehajtani, amely a lehetı legjobban szimulálja a jövıbeni mőködési
feltételeket, amit végrehajtási környezetnek nevezünk.

9
Horváth László Szoftvertesztelés a gyakorlatban

2. 4. Tesztelési alapelvek
Az elsı és talán legfontosabb alapelv a teszteléssel kapcsolatban a nyomonkövethetıség.
Ez egyrészt fontos a hibák pontos helyének felderítése szempontjából, másrészt pedig a
tesztek késıbbi megismételhetısége miatt. Egy teszt nem tekinthetı elfogadhatónak, ha
késıbb nem ismételhetı meg. Ennek a regressziós tesztelés során van nagy jelentısége, ahol
pont az a cél, hogy a korábban felfedett hibák javítása után meg kell ismételni a teszteket
annak érdekében, hogy kiderítsük, a javítás nem vitt-e újabb hibákat a rendszerbe.
A következı alapelv, hogy a teszteket már jóval a teszt konkrét futtatása elıtt meg kell
tervezni. Ugyanúgy, ahogy elkészítjük a rendszertervet, el kell készíteni egy teszt tervet is,
ami magában foglalja a tesztesetek pontos leírását, és azt, hogy mi az elvárt eredmény a
tesztelés során. Ettıl eltérni csak nagyon kivételes esetben lehet. Ez azért nagyon fontos, mert
így nem a teszt idomul a rendszerhez, hanem kénytelenek vagyunk a rendszert javítani
egészen addig, amíg minden elıre eltervezett teszt hibátlanul le nem fut.
A Pareto-elv kimondja, hogy a hibák 80%-a a kód 20%-ban fordul elı. Ez valószínőleg
azon alapszik, hogy a hibák általában csoportosan, csomósodva fordulnak elı. Ezt minden
programozó tapasztalhatta, aki készített már önállóan programot. Elıfordul, hogy egyetlen
hiba kijavítása tucatnyi egyéb rendellenesség javulásához vezet. Minden cégnél érdemes a
tipikus hibákról adatbázist készíteni, ami nagyban megkönnyítheti a tesztelık és a
programozók munkáját azáltal, hogy a leggyakoribb hibák után kutatnak saját rendszerükben,
lerövidítve így a tesztelés és a javítás idejét.
A tesztelést kezdjük mindig kicsiben és haladjunk a nagyobb részek felé. Elsı lépésben
tehát gyızıdjünk meg az eljárások, függvények helyes mőködésérıl, majd jöhetnek a
modulok, alrendszerek, és végül a teljes rendszer.
Egy korábban említett alapelvet itt is megemlítünk, hiszen így lesz teljes a felsorolás. Ez
az elv nem más, minthogy egyetlen modul vagy rendszer sem tesztelhetı hiánytalanul,
minden részletre kiterjedıen. Ennek két alapvetı oka van. Az elsı egy elméleti korlát, a
bizonytalanság problémája. Senki sem szeret úgy munkát végezni, hogy minden lépésben
ellenırzésnek vetik alá. A második egy sokkal kézzelfoghatóbb korlát, a költség és idıbeli
határok. A tesztelık terhelhetısége is véges.

10
Horváth László Szoftvertesztelés a gyakorlatban

2. 5. Ki teszteljen?

Ez egy folytonosan elıkerülı probléma, melynek szakmai és erıforrásbeli aspektusai is


vannak. Egyfelıl a tesztelést bízhatjuk a programozókra, akik a rendszert fejlesztik. Ez egy
költségkímélı megoldás, legalábbis rövidtávon. Ennek a megoldásnak az elınye, hogy a
programozó nyilván tökéletesen ismeri a kódot és a rendszer felépítését. A probléma az, hogy
a fejlesztı sokkal „könnyedebb” tesztelést végez, és hajlamos a kódolási hibák felett átsiklani
egyrészt, mert úgy gondolja biztos jól írta meg a programot, másrészt, mert kötik a határidık.
A rendszerben maradt hibák miatt a késıbbiekben újabb és újabb javítások kiadására
kényszerül a cég, így a hosszú távú költségek nagymértékben megnövekedhetnek. A másik
lehetıség, hogy külön tesztelı csapatot alkalmazunk, akiknek semmi más feladata nincs, mint
a rendszer tesztelése. Ez költségesebb rövidtávon, és a tesztelıknek a rendszer megismerésére
is idıt kell szánni, viszont sokkal pártatlanabb és alaposabb tesztnek vethetik alá a rendszert.

2. 6. Hibák típusai

A gyakorlatban leggyakrabban elıforduló hibák nagyobb csoportokba sorolhatóak,


amelyek ismerete megkönnyíti a tesztelık munkáját. A hibák csoportosítása a nagyjából
következı módon végezhetı el:
• Algoritmikus hibák: Ezek tipikusan emberi hibák eredményeként, a programozó
figyelmetlensége miatt állnak elı. Ilyen lehet a változó inicializálásának, vagy a ciklus
invariáns beállításának hiánya. Elıfordulhat, hogy a program nem kezeli a
nullpointert, nem azonos típusú változókat hasonlítunk össze, illetve elégtelen
hibakezelést alkalmazunk. Az ilyen fajta hibák egy része már fordítási idıben kiderül,
többségük azonban csak mőködés közben.
• Számítási és pontosságbeli hiányosságok: Sokszor elıfordul, hogy az algoritmus,
amelybıl a programozó kiindul, megfelelı, viszont a kódolás során hiányosan
(numerikus, adatstruktúrabeli hiányosságok) hibákkal kerül megvalósításra. Ezek
természetesen nem okoznak fordításbeli hibát, viszont a végrehajtás során komoly
problémákhoz vezethetnek.
• Dokumentációs hibák: Talán a legnehezebben felfedezhetı hibák azok, amelyeket a
rendszer dokumentálása során követünk el. Itt olyan problémákra kell gondolni, mint a
valós és a dokumentációban leírt mőködés közötti eltérés.

11
Horváth László Szoftvertesztelés a gyakorlatban

• Túlcsordulás hatására bekövetkezı hibák: Valószínőleg minden programozó számára


ismert probléma a túlcsordulás. Az adatszerkezetek, eljárások túllépik az elıre
meghatározott memóriamennyiséget, és a program futása megszakad (segmentation
fault). Ez a legjobb esetben csupán a rendszer leállásához vezet, súlyosabb esetben
adatvesztést okozhat.
• Kapacitásbeli problémák: A rendszer mőködése során eléri teljesítménye határait, és
bizonytalan állapotba kerül.
• Hardverrel és rendszerszoftverrel kapcsolatos problémák: A rendszerhez szállított
hardver és szoftverkörnyezet nem elégíti ki a dokumentációban foglalt mőködési
feltételeket. Ezek akár a cégtıl független hibák is lehetnek, amelyekért a beszállítókat
terheli a felelısség.
• Helyreállítási problémák: ezek a fajta hibák akkor válnak láthatóvá, ha egy más fajta
hiba már elızıleg bekövetkezett, és a visszaállítás után a rendszer nem úgy mőködik,
mint ahogy azt elvárnánk. Talán az ilyen típusú hibák a legveszélyesebbek a
felhasználók szempontjából, hiszen üzemzavarhoz és súlyos adatvesztéshez
vezethetnek.

2. 7. A tesztek osztályozása

Ez az egyetlen szó, hogy tesztelés, technikák egész skáláját foglalja magába, amelyek
mind különböznek egymástól, és változatos célokat szolgálnak. Két különbözı osztályozási
szintet különítünk el. Az elsı a rendszer részletessége alapján különbözteti meg a tesztelési
típusokat. Ez alapján megkülönböztetünk egység, integrációs és rendszer tesztet. Ezekrıl
késıbb még ejtünk pár szót. A másik fajta felbontás pedig fıleg a tesztelés módjára
vonatkozik. Itt megkülönböztetünk fekete (funkcionális) és fehér-doboz (strukturális)
tesztelést. Az alapvetı különbség a két módszer között, hogy a fekete-doboz teszt a specifikált
viselkedést vizsgálja a kód ismerete nélkül, míg az utóbbi a programozott viselkedést a kód
ismeretében. A közös ezekben a technikákban, hogy mind a specifikált és a programozott
viselkedés közötti különbségeket keresik. A kettı különbségét szemléletesen mutatja a
következı oldalon látható 2. 1. ábra.

12
Horváth László Szoftvertesztelés a gyakorlatban

Specifikált Programozott
(elvárt) (tapasztalt)
mőködés mőködés

Hiányos kód Helyes megvalósítás Felesleges kód

2. 1. ábra. A programozott és a specifikált viselkedés közötti különbség

Az ábráról leolvasható a korábban már tárgyalt fault két alapvetı okozója. Az elsı,
amikor a hiba olyan kódrészletnél váltódik ki, ami nem szerepelt a specifikációban
(felesleges kód). Ha pedig a tulajdonságot specifikáltuk, de nem programoztuk le, akkor
hiányos program okozta hibáról beszélünk.

Specifikált Programozott
(elvárt) 2 (tapasztalt)
mőködés mőködés

5 1 6
4 3

Tesztesetek
(ellenırzött
mőködés)

2. 2. ábra. A tesztesetek kapcsolata az elvárt és programozott viselkedéssel

Ha az elızı ábrát kiegészítjük a tesztkészlettel, akkor a 2. 2. ábrát kapjuk. Amint látjuk, a


tesztelés során csak egy szők részét fedjük le a valóságos kódnak, illetve a specifikált
tulajdonságoknak (1-es eset). A következı listában felsoroltuk, hogy mi a probléma a többi
részhalmazzal:
2: nem teszteltük le, de specifikáltuk, leprogramoztuk
3: leteszteltünk olyan részt, amit nem specifikáltunk

13
Horváth László Szoftvertesztelés a gyakorlatban

4: nincs leprogramozva, amit specifikáltunk


5, 6: nem teszteltünk olyan részeket, amiket specifikáltunk, illetve programoztunk
7: ennek igazából semmi értelme (mit tesztelek?)

Ha a specifikáció olyat tartalmaz, amihez nem készítettünk tesztesetet, akkor a tesztet


hiányosnak tekintjük. Ekkor ugyanis nem megfelelı mőködés léphet fel a használat során. Ha
azonban nem specifikált viselkedési elemeket tesztelünk, akkor az elvégzett munka
indokolatlan, vagy a specifikáció hiányosságára utal és jelzi, hogy a tesztelıknek is részt
kellene venni a specifikáció és a tervezés lépéseiben.
Felmerülhet a kérdés, hogy mikor milyen technikát használjuk. Nos a késıbbiekben
részletes példákat fogunk látni az egyes típusokra, most csak néhány alapszabályt közlünk.
Nem lehet elégszer hangsúlyozni, hogy a funkcionális tesztek tervezését már a specifikáció
részeként el kell kezdeni. Tisztában kell lennünk vele, hogy mit akarunk tesztelni, milyen
eszközökkel és milyen eredményt várunk a teszteléstıl. Fontos rögzíteni a felhasználó
igényeit és feltételeit az átvétellel kapcsolatban. A funkcionális tesztek elvégzése elkezdıdhet,
ha vannak kész unitok, mőködı egységek. Minél korábban kezdjük a tesztelést, annál kisebb a
valószínősége a helytelen mőködésnek. A strukturális tesztelés az implementációs fázis
részeként jelenik meg a szoftverfejlesztés során. Az egység (unit), integrációs és rendszer
tesztek ebben a sorrendben végezhetıek egymás után.

2. 8. A tesztelés szintjei, tevékenységek

A tesztelés során jól elkülöníthetı szinteket lehet megkülönböztetni. A dolgozatban fıleg


a unit tesztek szintjén vizsgálódunk, de a teljesség kedvéért itt megadjuk valamennyi szintet:
• Unit teszt: a legkisebb egységek, modulok, objektumosztályok, alrendszerek
tesztelése
• Integrációs teszt: az összeillesztett modulok és interfészek közötti interakciókban
keressük a hibákat. Két stratégia terjedt el az integráció során: a fentrıl lefelé és a
lentrıl felfelé való integrálás. Az egyik esetben a tesztelést a felsıbb szinteken
kezdjük, és lefelé haladva keressük a hibákat, míg a másodiknál a tesztelt
egységeket illesztjük egymáshoz felfelé haladva a hierarchiában.

14
Horváth László Szoftvertesztelés a gyakorlatban

• Rendszer teszt: az elkészült rendszer tesztelése annak érdekében, hogy igazoljuk,


hogy megfelel a követelményeknek.
• Elfogadási teszt: a megrendelı illetve a felhasználó által megfogalmazott
követelmények teljesülését vizsgáljuk. Ez a tesztelési fázis már általában a
megrendelı bevonásával történik, ı dönti el, hogy a rendszer elfogadható vagy
sem.
• Installációs teszt: az elfogadás után a rendszert a végsı mőködési környezetbe
integráljuk és ott vizsgáljuk a helyes mőködést.

A fejlesztés során rengeteg dolgot kell elvégeznünk és szinte minden folyamathoz


kapcsolható valamilyen tesztelési folyamat. A fejlesztés és a tesztelés közötti szoros
összefüggések legjobban egy ábrával szemléltethetıek.

Tesztelt
Alrendszer Rendszerterv Követelmény-
kódja Unit teszt alrendszer dokumentum dokumentum,
felhasználói kézikönyv
Tesztelt Integrált
alrendszer alrendszerek
Alrendszer
kódja Unit teszt Integrációs Mőködés
Tesztelt tesztelés tesztelése
alrendszer Mőködı
Fejlesztıi tesztek rendszer
Alrendszer
kódja Unit teszt

Felhasználói Megrendelı Általános


környezet elvárásai követelmények

Elfogadott Validált
Installációs rendszer Elfogadási rendszer Teljesítmény
teszt teszt teszt

Használható Felhasználói tesztek


rendszer
A rendszer
használatban

2. 3. ábra. Teszteléssel kapcsolatos tevékenységek

15
Horváth László Szoftvertesztelés a gyakorlatban

3. Funkcionális tesztelés

A funkcionális tesztnél a programra, mint input-output leképezésre tekintünk. A tesztelés


során az implementációt ismeretlennek tekintjük. Ezt a fajta szemléletet fekete doboz
megközelítésnek nevezzük. A lényeg, hogy olyan teszteseteket készítsünk, amik az
implementáció megváltozása esetén is megállják a helyüket. A tesztesetek fejlesztése
egyébként párhuzamosan folyik az implementációval. A fejezetben részletesen tárgyalt
funkcionális tesztelési módszerek az ekvivalencia-osztályozás, a határérték analízis, valamint
az ok-okozat analízis.

3. 1. Példák

A technikák bemutatásához ebben és a következı fejezetben is megpróbáljuk ugyanazokat a


példákat felhasználni. Így szembetőnıbbek lesznek a különbségek, és jobban látszanak az
eljárások erısségei, és gyengeségei is.

3. 1. 1. Háromszög probléma

Az elsı probléma, amivel foglalkozunk, a háromszög probléma, a leggyakrabban használt


példa a teszteléssel foglalkozó irodalomban. Az alapprobléma szerint adott egy program, ami
három egész számot vár a bemenetére (a, b, c). Ezek lesznek a háromszög oldalai. A program
kimenete nem más, mint a háromszög típusa: szabályos, egyenlıszárú, vagy általános
háromszög. Természetesen elıfordulhat, hogy a megadott számokból nem képezhetı
háromszög, ekkor a program a „Nem háromszög” válasszal tér vissza.
A probléma létezik egy kissé javított változata. Ahhoz, hogy a három szám egy
háromszög egy-egy oldala lehessen, ki kell elégíteniük a következı feltételeket:
c1.: 1 ≤ a ≤ 200 c4.: a < b+c
c2.: 1 ≤ b ≤ 200 c5.: b < a+c
c3.: 1 ≤ b ≤ 200 c6.: c < a+b

A program kimenetei között szerepelnek az elıbb felsoroltak, továbbá ha valamelyik input


érték nem felel meg az elıbb felsorolt követelményeknek, akkor errıl a felhasználó értesítést
kap.

16
Horváth László Szoftvertesztelés a gyakorlatban

Annak oka, hogy ez a példa ilyen elterjedt és ilyen hosszú idın keresztül megállja a helyét
az, hogy világos ám mégis komplex logikát tartalmaz. Rendkívül jól példázza továbbá a
megrendelık, a fejlesztık és a tesztelık közötti kommunikációs gondokat is. A specifikáció
feltételezi, hogy a készítık ismerik a háromszög tulajdonságait, legfıképpen azt, hogy egy
háromszög bármely két oldalának összege nagyobb a harmadik oldal hosszánál. Az oldalak
hosszára vonatkozó megkötés (maximum 200) önkényes és egyben kényelmes is. Ezt a
tulajdonságot késıbb a határérték tesztelésnél fogjuk kihasználni.

3. 1. 2. A „NextDate” probléma

A háromszög probléma jól példázza a bemenetek és a megfelelı kimenetek közötti


kapcsolatot. A NextDate függvényt egy másfajta probléma illusztrálására fogjuk használni. Itt
a hangsúly a bemeneti értékek közötti logikai kapcsolaton van.
A NextDate szintén három értéket vár bemenetül, úgymint év, hónap, és nap. Kimenetként
megmondja, milyen nap következik a megadott után. Természetesen a három változónak itt is
ki kell elégítenie néhány feltételt:
c1. 1 ≤ hónap ≤ 12
c2. 1 ≤ nap ≤ 31
c3. 1812 ≤ év ≤ 2012

Ahogy azt a háromszög problémánál tettük, most is finomíthatjuk a specifikációt. Ez


magában foglalja a helytelen értékő inputokra adott válaszok meghatározását, illetve
vizsgálhatjuk az érvénytelen változó kombinációkat is, mint amilyen például június 31-e.
Ez a függvény az elıbb említett bemeneti érték problémákon kívül felveti a szökıévek
kezelésének problémáját is. Mivel egy év 365, 2422 nap hosszú, a szökıéveket használjuk az
extra nap problémájának kiküszöbölésére. Egy évet szökıévnek tekintünk, ha osztható
néggyel, kivéve a századfordulókat. A századfordulók csak akkor tekinthetık szökıévnek, ha
a négyszáz többszörösei. A feltételek alapján tehát szökıévnek számít 1992, 1996, 2000 de
például 1900 nem.
Ez a két probléma végigkísér minket a tesztelési technikák tárgyalása során amellett, hogy
ha a helyzet úgy kívánja, bevezetünk majd kisebb lélegzető példákat is.

17
Horváth László Szoftvertesztelés a gyakorlatban

3. 2. Ekvivalencia-osztályozás

Több érv is szól amellett, hogy az ekvivalencia-osztályozást válasszuk tesztünk


alaptechnikájának. Elıször is meglesz a teljesség érzése a tesztelés befejezése után, másrészt
pedig kizárjuk a redundancia lehetıségét. A tesztadatok osztályozásával lehetıségünk nyílik a
tesztesetek számának csökkentésére, ami természetesen erıforrás megtakarításhoz vezet.
Az eljárás során a bemeneti értékeket ekvivalencia osztályokra bontjuk, és minden
osztályból veszünk egy reprezentánst, amivel a tesztet elvégezzük. Az ekvivalencia osztályok
tulajdonságai miatt, miszerint uniójuk elıállítja a teljes halmazt valamint, hogy nincs közös
elemük, biztosítja a teszt teljességét és redundancia mentességét. A tesztesetek számának
csökkenése természetesen attól is függ, hogyan választjuk meg az osztályozási feltételt.
A háromszög probléma esetében például, amikor a szabályos háromszögekre teszteljük a
programot elég, ha az (5, 5, 5) hármast adjuk meg bemenetként és szükségtelen például a (6,
6, 6), vagy a (100, 100, 100) esetek vizsgálata. Intuícióink alapján a program ezekre az
esetekre is hasonlóan viselkedik, éppen ezért redundanciát okoznának a tesztelésben. A
strukturális tesztelés tárgyalása során látni fogjuk, hogy a „hasonlóan viselkedik” azonos
végrehajtási utat jelent.
Az ekvivalencia osztályozás kulcsa és ereje az osztályozási feltételek megválasztásában
rejlik. Ez egy heurisztikus folyamat, melyhez elıször alaposan meg kell vizsgálni a lehetséges
bemeneti értékek tartományát. Lehetséges, ám mégis nagyon durva felosztás például az
érvényes és érvénytelen inputokra osztás. A gyakorlatban ahány feladat, annyiféle
osztályozás képzelhetı el. Mégis megadható néhány irányvonal, ami mentén el tudunk indulni
egy konkrét probléma esetében.

3. 2. 1. Irányvonalak az osztályozáshoz

Amennyiben a program valamely értéktartományban várja a bemeneti adatokat, akkor


három osztályt érdemes létrehozni. Az egyikben az érvényes inputok lesznek, míg a másik
kettıt a tartomány alatti, illetve feletti értékek alkotják. A háromszög probléma esetében
például a három osztály a következı lesz:
1. 1≤ x ≤200
2. x <1
3. x> 200

18
Horváth László Szoftvertesztelés a gyakorlatban

Ha egy olyan programot tesztelünk, amely egy konkrét értékkel dolgozik, akkor szintén
három osztályt érdemes létrehozni. Az egyikben csak az érvényes érték lesz, egy másikban
egy érték, ami kisebb az elvártnál a harmadikba pedig egy nagyobb érték kerül. Ez
természetesen olyan esetben, ha nem lehet háromértékő az input (például a logikai típus
esetében) két osztályra redukálódik és elıáll a klasszikus érvényes és érvénytelen inputok
esetére bontás. Gyakorlatilag a halmazok esetében is ez a helyzet. Veszünk egy értéket a
halmazból és egyet a halmazon kívülrıl.
Az itt felsorolt osztályozási módszereket természetesen mindig az aktuális probléma
szerint kell módosítani, miután alaposan áttanulmányoztuk a feladat specifikációját.
A következıkben tisztázzuk a különbséget a gyenge és az erıs ekvivalencia-osztályozás
között.

3. 2. 2. Gyenge ekvivalencia-osztály tesztelés

Tegyük fel, hogy adott egy F függvény, amely x1 és x2 értékeket kapja inputként. A két
számra a következı feltételek érvényesek:
a≤ x1 ≤d, ahol az [a, d] tartomány három résztartományból áll: [a, b),[b, c),[c, d)
e≤ x2 ≤g, ahol [e, g] szintén résztartományokra oszlik: [e, f), [f,g]

Láthatjuk, hogy az elsı értelmezési tartomány három ekvivalencia-osztályra bomlik, míg a


második kettıre.
A gyenge ekvivalencia-osztály tesztelés esetén minden ekvivalencia-osztályból kiveszünk
egy-egy elemet, és ezekbıl állítjuk össze a tesztesetet. Az elıbb ismertetett rövid példát
könnyen szemléltethetjük koordináta rendszer segítségével. A 3. 1. ábrán bemutatjuk a
gyenge osztályozás esetét.

19
Horváth László Szoftvertesztelés a gyakorlatban

X2

X1
a b c d
3. 1. ábra. Gyenge ekvivalencia-osztályozás

Az ábrán látható három teszteset mindegyikében mindkét értelmezési tartományból egy-


egy résztartományt (ekvivalencia-osztályt) használtunk fel. Ezeket szisztematikus módon
egymás után választjuk ki, és végül kialakul az ábrán látható elrendezés. Valójában a gyenge
ekvivalencia-osztályozás esetén a tesztesetek száma meg fog egyezni a nagyobb osztályszámú
halmaz részosztályainak számával (ez a példában három).

3. 2. 3. Erıs ekvivalencia-osztály tesztelés

Az erıs ekvivalencia-osztály tesztelés az együttes hibamegjelenés feltevésébıl indul ki.


Éppen ezért az ekvivalencia-osztályok kombinációjának mindegyikébıl szükségünk van
tesztesetekre. Ezt szemléltetjük a 3. 2. ábrán. Az alkalmazott koordinátarendszeres eljáráson
jól megfigyelhetı a tesztesetek kialakításának egyszerősége és logikája. Van továbbá bennünk
egyfajta teljesség érzés is a módszerrel szemben, hiszen lefedtük az összes ekvivalencia-
osztályt, és elıállítottuk az összes lehetséges kombinációját az inputértékeknek. A tesztesetek
száma ebben az esetben megegyezik az ekvivalencia-osztályok számának szorzatával, azaz
jelen esetben 2 * 3 = 6 eset.
A jó osztályozás kulcsa az ekvivalencia kapcsolatok megfelelı megválasztása. A legtöbb
esetben az osztályozást az input adatokon végezzük el. Igazából nincs különösebb oka annak,
hogy ezt nem az output értékek tartományán tesszük meg. Talán némileg egyszerőbb így
végezni a tesztelést, mintha még vissza kellene keresni a kimeneti tesztesethez, hogy milyen

20
Horváth László Szoftvertesztelés a gyakorlatban

bemenet generálja azt, továbbá a példáinkhoz is jobban illeszkedik az a szemlélet, hogy a


bemeneti értékeket osztályozzuk.

X2

X1
a b c d
3. 2. ábra. Erıs ekvivalencia-osztályozás

3. 2. 4. Gyenge robusztus ekvivalencia-osztály tesztelés

Az elnevezés elsıre talán kicsit ellentétesnek tőnhet. Hogy lehet valami egyben gyenge és
robusztus is? A robusztusság abból adódik, hogy figyelembe vesszük az érvénytelen inputokat
is. Az eljárás gyenge volta pedig az egyszerő hibamegjelenéssel kapcsolatos szemléletre utal.
Régen nevezték ezt az eljárást hagyományos ekvivalencia-osztályozásnak is. A módszer,
amellyel a teszteseteket elıállítjuk, gyakorlatilag két lépésbıl tevıdik össze:
1. Az érvényes inputokra válasszunk adatokat, a gyenge ekvivalencia-osztályozáshoz
hasonlóan. Itt minden érték, ami a tesztesetben szerepel érvényes tartománybeli.
2. Érvénytelen inputok esetén pedig választunk egy értéket valamely érvénytelen
tartományból a többit pedig, ami a tesztesetben szerepel, érvényes osztályokból
kell választani. Ebben a lépésben használjuk ki az egyszerő hibamegjelenés elvét,
vagyis, hogy egyszerre csak egy adat lehet hibás.

Ezzel a tesztelési stratégiával elıállított tesztesetek láthatóak a 3. 3. ábrán.

21
Horváth László Szoftvertesztelés a gyakorlatban

X2

X1
a b c d
3. 3. ábra. Gyenge robusztus ekvivalencia-osztályozás

Két probléma merül fel a robusztus ekvivalencia teszteléssel kapcsolatban. Az elsı, hogy
a specifikációban gyakran nem rögzítik, hogy mik az elvárt kimeneti értékek egy érvénytelen
teszteset esetén. (Próbálhatunk azzal érvelni, hogy ez a specifikáció hiányossága, de ez sajnos
nem oldja meg a problémát.) Éppen ezért a tesztelık rengeteg idıt töltenek azzal, hogy
kimeneti értékeket definiáljanak ezekre az esetekre. A második probléma az, hogy az erısen
típusos nyelvek kiküszöbölik a hibás értékekkel kapcsolatos problémákat. Az ekvivalencia-
osztályozás azokból az idıkbıl származik, amikor a COBOL és FORTRAN nyelveket
használták programok írására, vagyis ezek a problémák egyformán fontosak voltak mindenki
számára. Tény, hogy az ehhez hasonló problémák nagyban hozzájárultak a típusos nyelvek
elterjedéséhez.

3. 2. 5. Erıs robusztus ekvivalencia-osztályozás

Az elızı pont alapján mindenkinek lehet némi elképzelése a technika lényegérıl. A dolog
robusztus része a hibás értékek figyelembevételébıl adódik, míg az erıs jelzı a többszörös
hiba elıfordulás lehetıségébıl ered. A teszteseteket, ahogy a 3. 4.-es ábrán is látszik, úgy
kapjuk, hogy az input érték tartományok mindegyikébıl veszünk egy-egy elemet, beleértve az
érvénytelen értékek tartományát is.
A tesztesetek meghatározásához általánosságban elmondható, hogy érvényes osztályok
esetén úgy próbáljuk meghatározni a teszteseteket, hogy minél több osztályt lefedjünk, míg
érvénytelen osztályokhoz mindig egyedi tesztesetet kell készíteni. A cél mindkét esetben az

22
Horváth László Szoftvertesztelés a gyakorlatban

osztályok teljes és hiánytalan lefedése. Ha ez sikerült, akkor a tesztet érvényesnek tekintjük az


elkészített tesztkészlettel.

X2

X1
a b c d
3. 4. ábra. Erıs robusztus ekvivalencia-osztályozás

3. 2. 6. Ekvivalencia-osztály tesztesetek a háromszög problémára

Az osztályozási technikák ismertetése után az alábbiakban bemutatjuk a háromszög


probléma ekvivalencia-osztályozásának módját.
A probléma ismertetése során felsoroltuk a lehetséges output értékeket: nem háromszög,
szabályos háromszög, egyenlı szárú háromszög, általános háromszög. Ezeket felhasználva
elkészíthetjük az ekvivalencia-osztályokat:

R1 = {<a, b, c>: a, b, c oldalú szabályos háromszögek}


R2 = {<a, b, c>: a, b, c egyenlı-oldalú háromszögek}
R3 = {<a, b, c>: a, b, c oldalú általános háromszögek}
R4 = {<a, b, c>: az a, b és c oldalak nem alkotnak háromszöget}

Mivel az a, b és c változóknak nincs valós alosztálya, így az erıs és gyenge ekvivalencia


osztályozás, hasonló eredményt szolgáltat (3. 1. táblázat). Ha figyelembe vesszük, hogy
milyen érvénytelen értékeket vehetnek fel az input értékek, megkapjuk a feladathoz tartozó
gyenge robusztus teszteléshez tartozó teszteseteket (3. 2. táblázat).

23
Horváth László Szoftvertesztelés a gyakorlatban

A táblázatból kitőnik, hogy külön kell tesztelni a felsı határon túli és az alsó határ alatti hibás
értékekre. A tesztesetek száma 3*2 = 6 lesz.

Teszteset neve a b c Elvárt kimenet


GYN1 5 5 5 Szabályos háromszög
GYN2 2 2 3 Egyenlıszárú háromszög
GYN3 3 4 5 Általános háromszög
GYN4 4 1 2 Nem háromszög

3. 1. táblázat. Gyenge ekvivalencia-osztály tesztesetek a háromszög problémára

Teszteset neve a b c Elvárt kimenet


GYR1 -1 5 5 Az a változó értéke kívül esik a megengedett tartományon.
GYR2 5 -1 5 A b változó értéke kívül esik a megengedett tartományon.
GYR3 5 5 -1 A c változó értéke kívül esik a megengedett tartományon.
GYR4 201 5 5 Az a változó értéke kívül esik a megengedett tartományon.
GYR5 5 201 5 A b változó értéke kívül esik a megengedett tartományon.
GYR6 5 5 201 A c változó értéke kívül esik a megengedett tartományon.

3. 2. táblázat. Gyenge robusztus ekvivalencia-osztály tesztesetek a háromszög problémára

Testeset neve a B c Elvárt kimenet


ER1 -1 5 5 Az a változó értéke kívül esik a megengedett tartományon.
ER2 5 -1 5 A b változó értéke kívül esik a megengedett tartományon.
ER3 5 5 -1 A c változó értéke kívül esik a megengedett tartományon.
ER4 -1 -1 5 Az a és b változók értéke kívül esik a megengedett tartományon.
ER5 5 -1 -1 A b és c változók értéke kívül esik a megengedett tartományon.
ER6 -1 5 -1 Az a és c változók értéke kívül esik a megengedett tartományon.
ER7 -1 -1 -1 Az a, b, c változók értéke kívül esik a megengedett tartományon.

3. 3. táblázat. Erıs robusztus ekvivalencia-osztály tesztesetek a háromszög problémára

24
Horváth László Szoftvertesztelés a gyakorlatban

Legvégül a 3. 3. táblázatban megadtuk az erıs robusztus ekvivalencia-osztályozással


elıálló teszteseteket. Látható, hogy itt egy idıben több változó is felvehet érvénytelen értéket.
Amennyiben három dimenzióban ábrázolnánk az eljárást oly módon, hogy a háromszög
oldalai lennének az x, y és z tengelyek, akkor könnyen elképzelhetı, hogy a (-1, -1, -1)
teszteset a kialakuló kocka egyik sarkában foglal helyet.
Az ekvivalencia-osztály tesztelés természetesen érzékeny a feltételek megválasztására,
amelyek alapján kialakulnak az osztályok. Ezen a ponton van szükség a tesztelı szakmabeli
tapasztalatára és tudására. Amennyiben az ekvivalencia-osztályokat az input tartomány
alapján határozzuk meg, a tesztesetek egy sokkal gazdagabb halmazát kapjuk. Milyen
lehetséges viszonyban állhatnak egymással az a, b és c egész számok? Lehetnek mind
egyenlık, páronként egyenlık, és az is elıfordulhat, hogy mindhárom érték különbözı. Ezek
alapján a következı osztályokat kapjuk:
D1 = {<a, b, c> : a = b = c}
D2 = {<a, b, c> : a = b, a ≠ c}
D3 = {<a, b, c> : a = c, a ≠ b}
D4 = {<a, b, c> : b = c, a ≠ b}
D5 = {<a, b, c> : a ≠ b, a ≠ c, b ≠ c}

A felsorolt öt halmaz mellé felvehetünk még néhányat, ha azt az esetet is megvizsgáljuk,


amikor a három oldal nem alkot háromszöget. Ha például az <1, 4, 1> számhármast
vizsgáljuk, akkor igaz, hogy van két egyenlı oldala, de ezek az oldalak nem alkotnak
háromszöget.
D6 = {<a, b, c> : a ≥ b + c}
D7 = {<a, b, c> : b ≥ a + c}
D8 = {<a, b, c> : c ≥ a + b}

Ha még inkább szét akarjuk szedni az osztályokat, akkor megtehetjük, hogy külön vesszük a
„kisebb mint” és az egyenlı eseteket.
D6’= {<a, b, c> : a = b + c}
D6’’= {<a, b, c> : a > b + c}

A másik két osztályra (D7, D8) hasonlóan elvégezhetı a bıvítés.

25
Horváth László Szoftvertesztelés a gyakorlatban

3. 3 Határérték tesztelés

Egy függvény két halmaz elemei között teremt kapcsolatot. Az elsıbıl kivett elemhez,
hozzárendeli a második halmaz egy elemét. Ezeket szokás, értelmezési tartománynak és
értékkészletnek nevezni. Egy program is felfogható egyetlen függvényként, amelynek
bemeneti értékei alkotják az értelmezési tartományt, kimeneti értékei pedig az értékkészletet.
Az input tartomány vizsgálatán alapuló tesztelési technikák talán a legismertebbek és
legelterjedtebbek. Ebben és a következı fejezetben megvizsgáljuk, hogyan lehet felhasználni
egy program funkcionális jellemzıit a tesztesetek azonosítására.

3. 3. 1 Határérték analízis

Az érthetıség és az egyszerőség kedvéért a korábbihoz hasonlóan elıbb azon az F


függvényen mutatjuk be a technikát, amely két értéket vár bemenetként. Most azonban
egyszerősítünk a tartományokat meghatározó feltételeken, és összesen két, balról és jobbról
egyaránt zárt, intervallumon vizsgálódunk.
a ≤ X1 ≤ b
c ≤ X2 ≤ d

A függvényünk bemeneti érték tartománya most is könnyen ábrázolható koordináta


rendszer segítségével, ahogy a 3. 5. ábrán látható. Bármely pont, amely a satírozott részen
belül található, érvényes input érték lesz.

X2

X1
a b
3. 5. ábra Kétváltozós függvény input tartománya

26
Horváth László Szoftvertesztelés a gyakorlatban

A határérték analízis alkalmazása során a határértékekre fókuszálunk, hogy teszteseteket


készítsünk. A technika alkalmazása mögött az a racionális elgondolás áll, hogy a hibák
általában az inputtartományok széleinél tömörülnek. A ciklusfeltételek esetében például „<”
operátort írunk a kódolás során „≤” helyett, így eggyel csökkentve a szükséges lefutások
számát, ami pedig már hozza magával a többi hibát.
A határérték analízis alapját az input értékek kiválasztásának módja képezi. A
teszthalmazba bekerül az érvényességi tartomány minimuma, a minimumnál eggyel nagyobb
érték, egy átlagos érték, a maximumnál eggyel kisebb, valamit a maximum érték. Manapság
rengeteg ingyenes és kereskedelmi szoftver áll rendelkezésre, amelyek segítségével
elvégezhetı egy program határérték analízise.
A határérték analízis egy rendkívül erıs feltevésen alapul. Ez a feltevés nem más, mint az
egyszerő hiba elıfordulás elve (errıl már volt szó az osztályozással foglalkozó fejezetekben).
Ez az elv azt fogalmazza meg, hogy a mőködés során elıforduló hibák (failure) többségének
egyetlen kiváltó oka van (fault) és csak nagyon ritkán fordul elı, hogy egy idıben több dolog
eredményezi ugyanazt a hibát. Ily módon a határérték analízisben szereplı tesztesetekben, egy
változó kivételével, az összes többi a normál értékét veszi fel, és csak annak az egynek az
értékét változtatjuk. Példaként elkészítjük az F kétváltozós függvényhez tartozó tesztkészletet:

{<X1átl, X2min>,<X1átl, X2min+>,<X1átl, X2átl>,<X1átl, X2max->,<X1átl, X2max>,


<X1min, X2átl>,<X1min+, X2átl>,<X1átl, X2átl>,<X1max-, X2átl>,<X1max, X2átl>}

A határérték analízis általánosítása

Az alap eljárás két módon is általánosítható: a változók számának és a tartományok


jellegének változásával. A változók számára való általánosítás egyszerő. Ha van egy n
változós függvényünk, akkor egy kivételével mindet egy átlagos értékre állítjuk be és
hagyjuk, hogy a kimaradt változó felvegye min, min+, áltagos, max-, és max értékét.
Megismételve ezt az összes értékkel, könnyen ellenırizhetı, hogy egy n változós függvény
teszteléséhez 4n + 1 teszteset szükséges.
A tartományokra vonatkozó általánosítás nagyban függ a változók természetétıl,
pontosabban a változók típusától. Ha a NextDate függvényünket tekintjük, annak a bemeneti
értékei hónapok, napok, és évek. Egy FORTRAN típusú nyelv esetén a hónapokat nyilván
számokkal helyettesítenénk {1, … ,12}. Egy olyan programozási nyelvben azonban, amely

27
Horváth László Szoftvertesztelés a gyakorlatban

engedi saját típus definiálását, létrehoznánk a hónap felsorolási típust {január, február, … ,
december} és ezt alkalmaznánk a függvény elkészítéséhez. Azonban mindkét módszer esetén
egyértelmő számunkra, a teljes programot megvizsgálva, hogy mit jelent a min, a min+, max
és max- érték. Amikor egy változó diszkrét korlátos érték tartománnyal rendelkezik, ezen
értékek meghatározása szintén egyértelmő. Azonban ha nincsenek jól meghatározott határai a
bemeneti értékeknek, akkor általában nekünk magunknak kell mesterséges határokat
megállapítani. Ha például a háromszög probléma alap megfogalmazását tekintjük, ott nem
voltak meghatározva az alsó és felsı határok. Alsó határt találni nem nehéz, az 1 lesz. Ez
abból a természetes igénybıl ered, hogy negatív oldalhosszúságú háromszög nem létezik. A
felsı határ megállapítása már nehezebb kérdés. Megtehetnénk, hogy a legnagyobb
ábrázolható számot tekintjük felsı határnak. Ilyen MAXINT - nek nevezett érték a legtöbb
nyelvben létezik és gond nélkül használható mőveletekhez. Egy másik lehetıség, ha
önkényesen kijelölünk egy felsı határt az oldalak hosszúságára vonatkozóan, mint ahogy azt a
bıvített megfogalmazásban mi is megtettük, amikor 200 – ra állítottuk be a legnagyobb
értéket.
A határérték analízis alkalmazása logikai változók esetében nehézkessé válhat, hiszen a
minimum és maximum értékek az igaz, illetve a hamis feltételek lesznek. Mi a helyzet
azonban a további három értékkel? A késıbbiekben látni fogjuk, hogy a logikai változók
tesztelésére ez a technika nem igazán alkalmas, helyette a döntési tábla alapú tesztelés
javasolt.

A határérték analízis korlátai

A határérték analízis kitőnıen alkalmazható azokban az esetekben, amikor a függvény


olyan paraméterekkel dolgozik, amelyek egymástól függetlenek egy jól meghatározott
tartományból veszik fel értéküket. A függetlenség egy fontos tulajdonság, amely például a
NextDate függvény esetében, némileg sérül. Különös kapcsolat áll fenn ugyanis a hónapok,
napok és évek között. Nem mindegy, hogy egy év szökıév vagy sem, illetve a napok
lehetséges száma is függ a hónapoktól.
A határérték analízis rendelkezik bizonyos hiányosságokkal, aminek legfıbb oka az, hogy
hiányoznak belıle saját ösztöneink és elképzeléseink. Aki azonban ezt elfogadja, egy
praktikus, és egyszerő tesztelési eljárást kap kézhez, amely rendkívül jól automatizálható.

28
Horváth László Szoftvertesztelés a gyakorlatban

A tartományok jó lehatároltsága is fontos szempont. Amikor a változók egy fizikai


jelenség mérésére szolgálnak, mint például hımérséklet, nyomás, sebesség, támadási szög,
akkor a határok jelentısége óriási. Nagyszerő gyakorlati példa a Phoenix -i repülıtér esete.
1992 nyarán a repülıtérnek be kellett zárni, mert a pilóták képtelenek voltak néhány eszközt
használni a repülın. Ennek oka az volt, hogy a berendezéseknél 120○F fokos maximum
hımérsékletet állítottak be és aznap a repülıtéren 122○F volt.
Érdekes lehet azon is elgondolkozni, hogy milyen hibákra lehetne fényt deríteni olyan PIN
kódokkal, mint 0000, 0001, 5000, 9998, vagy a 9999.

3. 3. 2. Robusztusság-teszteléss

A robusztusság tesztelése a határérték analízisnek egy egyszerő kiterjesztése. A legtöbb


leírás a határérték analízist eleve ezzel a technikával mutatja be, és nem tesz különbséget
köztük.
Az eljárás lényege, hogy az eddigi öt tesztértéket kiegészítjük két további esettel. Meg kell
vizsgálni, mi történik, ha a tesztérték nagyobb, mint a tartomány felsı határa (max+), illetve
kisebb, mint a minimum érték (min-). Korábban ismertettük a kétváltozós függvényre
vonatkozó tesztkészletet. A robusztusság teszteléséhez fel kell venni még néhány esetet az
eddigiek mellé. A kialakuló tesztkészletet a 3. 6.-es ábrán láthatjuk.

X2

X1
a b
3. 6. ábra. Robusztusság tesztelés

29
Horváth László Szoftvertesztelés a gyakorlatban

A technika érdekessége azonban nem a bemeneti értékek kiválasztásában rejlik, hanem az


elvárt kimeneti értékekben. Mi történik, ha egy fizikai mennyiség eléri a maximumát? Ha
például ez a támadás szöge egy repülıgép szárnyain, akkor a légterelık rögzülhetnek, a repülı
irányíthatatlanná válhat. Ahogy azt korábbi példánkban láttuk a hımérséklet is gondot
okozhat (Phoenix -i repülıtér esete). Ha egy lift maximum terhelésérıl van szó, akkor
reménykedünk, hogy semmi különös nem történik, a felvonó automatikája ezt jelzi, az ajtó
kinyílik, és a felvonó nem indul el. Ha pedig egy érvénytelen naptári napról van szó, mint
amilyen a május 32. akkor hibajelzést kapunk. A robusztusság tesztelés fı ereje tehát abban
rejlik, hogy nagy hangsúlyt fektet a hibakezelésre. Erısen típusos nyelvek esetében a
robusztusság tesztelése nehézkes lehet. A Pascal nyelv esetében például, ha egy változó elıre
meghatározott tartományból veheti fel az értékét, akkor nem tudjuk meghívni minimum alatti,
illetve maximum feletti értékekkel, mert ez futás idejő hibát okoz. Ez felvet egy érdekes
problémát az implementációval kapcsolatban. Jobb, hogy ha explicit határokat készítünk, és
hibakezelés alkalmazásával oldjuk meg a robusztus értékek kezelését, vagy pedig maradjunk
az erıs típusosságnál?

3. 3. 3. „Legrosszabb eset” tesztelés

Ahogy azt korábban említettük, a határérték analízis az egyszerő hiba elıfordulás elvét
alkalmazza a megbízhatóság vizsgálata során. Ha elutasítjuk ezt a feltételt, akkor azt is
megvizsgálhatjuk, hogy mi történik, ha több változó is extrém értéket vesz fel. Vizsgáljuk
meg a problémát a jól ismert kétváltozós függvényen keresztül. Az eljárás úgy indul, hogy az
eddigiekhez hasonlóan mindkét változóhoz elkészítjük az öt értéket tartalmazó (min, min+,
átlagos, max-, max) teszthalmazt. Ezután a halmazok tagjaiból rendezett párokat készítünk. A
lehetséges esetek száma 5*5 = 25 lesz. Az 3. 7.-es ábrán koordináta rendszerben ábrázolva
láthatjuk a tesztkészletet.

30
Horváth László Szoftvertesztelés a gyakorlatban

X2

X1
a b
3. 7. ábra. „Legrosszabb eset” tesztkészlet kétváltozós függvényre

Egy kicsit végiggondolva az eddig olvasottakat láthatjuk, hogy a határérték analízis során
kapott tesztesetek részhalmazát képezik a „legrosszabb eset” tesztelés során kialakulónak. A
tesztesetek száma is ugrásszerően megnı, hiszen a határérték analízis során, egy n változós
függvényt tekintve, 4n+1 tesztesetre volt szükségünk, míg most 5n-re.
A legrosszabb-eset tesztelés jól illeszkedik az eddigi sorozatba melynek során
kiterjesztettük az egyszerő határérték analízist, és ugyanazokkal a hibákkal és korlátokkal
rendelkezik. Az eljárás a legjobban talán olyan rendszerek esetén alkalmazható, ahol a
változók számos különféle módon léphetnek interakcióba egymással, és így megnı a
hibalehetıségek száma is, valamint nagy a hibák bekövetkezésébıl eredı többletköltség.
Amennyiben szükségünk lenne egy minden eshetıségre és hibára felkészülı tesztelési
eljárásra, akkor alkalmazhatnánk egy robusztus-legrosszabb eset technikát. Ennek a
legnagyobb a költsége is (egy kétváltozós függvény esetén 49 teszteset!) és ezért a
gyakorlatban nem igazán alkalmazzák, hiszen a legtöbb hiba elıfordulás kiszőrhetı a két
eljárás külön alkalmazásával.

3. 3. 4. Tesztelés speciális értékekkel

Talán ez az a technika, amelyet legszélesebb körben használnak funkcionális tesztelésre.


Egyben ez a leginkább intuitív módon végezhetı, kevésbé formális eljárás. A speciális
értékekkel való tesztelés során a tesztelı saját általános ismereteire és más szoftverekkel

31
Horváth László Szoftvertesztelés a gyakorlatban

kapcsolatos tapasztalataira hagyatkozik. Az egyetlen irányvonal, amit itt meg lehetne


fogalmazni az, hogy használjuk a legjobb tudásunkat a tesztelés során!
Ez a technika nagyon hasznos lehet egy szoftver megbízhatóságának és képességeinek
tesztelése során. Sokszor elıfordul, hogy egy jól megválasztott, speciális értékekbıl
összeállított tesztkészlet sokkal eredményesebben tárja fel a hibákat, mint eddigi technikákkal
automatikusan generáltak. Egy jó tesztelı például a NextDate függvény esetében, nagyobb
hangsúlyt fektet olyan dátumokra, mint a február 28. , 29. és a szövıévek.

3. 3. 5. Példák

Az általunk tárgyalt példák esetében valamennyi most ismertetett eljárás szemléltetése


nagyon helyigényes feladat lenne, így itt most csak néhányat vizsgálunk meg, és ezekhez sem
mindig szerepel táblázatos formában a megoldás.

Tesztesetek a háromszög problémára

A feladat alap kiírásában nem szerepelt semmiféle megkötés a háromszög oldalaira


vonatkozóan csak, hogy egész számok legyenek. Az alsó határ nyilván 1, és mi felsı határnak
a 200-at választottuk. Az 3. 4.-es táblázatban látható a háromszög probléma határérték
analíziséhez tartozó tesztkészlet.
A táblázat elkészítéséhez elıször végig kell gondolni, mik lesznek a specifikáció alapján a
min, min+, átlagos, max- és max értékek. Ezek rendre az 1, 2, 100, 199, 200 számok lesznek.
A következı lépésben, a korábban ismertetett módon, mindig két változó értékét az átlagoson
tartva a harmadik értékét végigfuttatjuk a lehetséges öt értéken. Ez jelen esetben viszonylag
könnyen kezelhetı számú tesztesethez vezet. A korábban meghatározott 4n + 1 szükséges
teszteset szám alapján ez 13 lesz. A táblázatban ugyan 15 sor van, de látható, hogy az egyenlı
oldalú háromszög esete háromszor szerepel (dılt betős sorok). Ezt az esetet természetesen
elég csak egyszer lefuttatni.

32
Horváth László Szoftvertesztelés a gyakorlatban

Teszteset sorszáma a b c Elvárt kimenet


1 100 100 1 Egyenlı szárú háromszög
2 100 100 2 Egyenlı szárú háromszög
3 100 100 100 Egyenlı oldalú háromszög
4 100 100 199 Egyenlı szárú háromszög
5 100 100 200 Nem háromszög
6 100 1 100 Egyenlı szárú háromszög
7 100 2 100 Egyenlı szárú háromszög
8 100 100 100 Egyenlı oldalú háromszög
9 100 199 100 Egyenlı szárú háromszög
10 100 200 100 Nem háromszög
11 1 100 100 Egyenlı szárú háromszög
12 2 100 100 Egyenlı szárú háromszög
13 100 100 100 Egyenlı oldalú háromszög
14 199 100 100 Egyenlı szárú háromszög
15 200 100 100 Nem háromszög

3. 4. táblázat. A háromszög probléma határérték analízise

A legrosszabb eset teszteléshez a változókra ugyanazok az értékek alkalmazhatóak (1, 2,


100, 199, 200), csak az összes lehetséges módon kell összetársítani a három változó értékeit.
Ez egy 53 = 125 sorból álló táblázatot eredményez, amely itt nem szerepel. Annyi
végiggondolható a táblázat elkészítése nélkül is, hogy a szélsıséges értékek rendezett
hármasokká szervezése miatt túlnyomó többségben lesznek azok a tesztesetek, amelyekre az
elvárt érték a „Nem háromszög” lesz.

Tesztesetek a „NextDate” problémára

A problémában szereplı változók az év, hónap és nap. A hozzájuk tartozó határérték


teszteléshez szükséges értékek pedig a 3. 2. – es táblázatban láthatóak.

33
Horváth László Szoftvertesztelés a gyakorlatban

Érték neve Év Hónap Nap


min 1812 1 1
min+ 1813 2 2
átlagos 1912 6 15
max- 2011 11 30
max 2012 12 31

3. 5. táblázat. A NextDate probléma változóihoz tartozó teszt értékek

Ezek után a határérték analízis és a legrosszabb eset tesztelés a háromszög problémához


hasonlóan elvégezhetı. Itt megint csak a határérték analízishez elkészített tesztkészlet
szerepel táblázatos formában, a legrosszabb eset teszteléshez tartozó nem. A redundáns esetek
ismét dılt betővel láthatóak (1912.6.15).

Teszteset sorszáma Év Hónap Nap Elvárt kimenet


1 1912 6 1 1912. 6. 2.
2 1912 6 2 1912. 6. 3.
3 1912 6 15 1912. 6. 16.
4 1912 6 30 1912. 7. 1.
5 1912 6 31 Hiba!
6 1912 1 15 1912. 1. 16.
7 1912 2 15 1912. 2. 16.
8 1912 6 15 1912. 6. 16.
9 1912 11 15 1912. 11. 16.
10 1912 12 15 1912. 12. 16.
11 1812 6 15 1812. 5. 16.
12 1813 6 15 1813. 5. 16.
13 1912 6 15 1912. 5. 16.
14 2011 6 15 2011. 5. 16.
15 2012 6 15 2012. 5. 16.

3. 6. táblázat. A „NextDate” problémához tartozó határérték analízis tesztkészlete

34
Horváth László Szoftvertesztelés a gyakorlatban

Két teljesen eltérı jellegő problémáról van szó, azonban a technika tökéletesen
alkalmazható mindkét esetben és a tesztesetek száma is ugyanannyi lesz. Látható tehát, hogy a
tesztelés erıforrásigénye nem a változók jellegétıl, hanem azok számától függ.

3. 4. Ok-okozat gráfok és a döntési tábla

Valamennyi funkcionális tesztelési mód közül azok a legszigorúbbak és egyben a legtöbb


gondolkodást igénylık, amelyek a döntési tábla alkalmazásán alapulnak, hiszen itt tisztán
logikai alapon fogalmazzuk meg a szükséges teszteseteket. Az irodalomban gyakran külön
választják az ok-okozat gráfokat és a döntési táblázatokat, itt azonban közösen tárgyaljuk
ıket, hiszen szoros összefüggés van közöttük és a gráfok alkalmazása, megkönnyítheti a
táblázat kialakítását.

3. 4. 1. Ok-okozat gráfok

A szoftver tesztelése sokkal egyszerőbb lehetne, ha a teszteseteket automatikusan


generálhatnánk a követelmények alapján. Ehhez nyújtanak segítséget az ok-okozat gráfok.
Egy gráf kialakítása során elsı lépésként alaposan át kell tanulmányozni a funkcionális
követelményeket. A feladat pontos megfogalmazása és megértése elengedhetetlen az eljárás
használatához. Ha ezzel megvagyunk, akkor beszámozunk minden okot és okozatot (hatást),
amivel találkoztunk. Ezek után már fel tudjuk rajzolni a gráf csúcsait. Az elıbb számot kapott
logikai feltételek közül az okok kerülnek balra a gráfban, míg az okozatok jobbra.
Összeköthetjük az okokat az általuk kiváltott hatásokkal és meg is kaptuk a számunkra
szükséges ok-okozat gráfot. A gráf egyszerősítése érdekében extra csúcsokat is
bevezethetünk. Tegyük fel például, hogy egy olyan feltételünk van, amely egy „vagy”
kapcsolatot tartalmaz. Ekkor nyilván a diszjunkció mindkét oldalán álló feltételbıl ugyanoda
vezetnének élek. Ezt elkerülendı bevezetünk egy harmadik csúcsot, amelybe élet húzunk
mindkét feltételbıl és ezek után a közös csomópontot használjuk a további függıségek
meghatározására.
A gráfok készítése során használatos jelölésekkel kapcsolatban kialakultak bizonyos
szabványok, amelyeket érdemes betartani.

35
Horváth László Szoftvertesztelés a gyakorlatban

Ha A akkor B Ha (A és B) akkor C

Ha (A vagy B) akkor C Ha ¬(A és B) akkor C

Ha ¬(A vagy B) akkor C Ha ¬A akkor B

3. 8. ábra. Az ok-okozat gráfokhoz használatos jelölések

3. 4. 2. Döntési tábla

A döntési táblákat az 1960-as évek óta használják a feladatban megfogalmazott logikai


kapcsolatok reprezentálására. Nagyon jól alkalmazhatóak olyan esetben, amikor sokféle
logikai kapcsolatot tartalmazó feladathoz kell teszteseteket generálni.
Egy döntési tábla alapvetıen négy részbıl tevıdik össze. Elıször a sorokat elnevezzük az
ok-okozat gráfoknál megállapított okokkal, majd alájuk felsoroljuk a hatásokat. A tesztesetek
az oszlopokban fognak kialakulni. Minden egyes oszlopban feltüntetjük, hogy a tesztesetben
teljesül-e egy feltétel és, hogy mi a feltétel kombinációhoz tartozó hatás. Példaként tekintsük a
3. 7. – es táblázatban látható döntési táblát.
Ha egy feltétel igaz egy tesztesetben, akkor azt a táblázatban I betővel jelöljük, míg hamis
esetben H betővel. Azokban az esetekben, amikor egy input érték nem befolyásolja az
eredményt, egy x-et teszünk a változóhoz. A kimenetek esetében a P (pass - teljesül) jelenti a
bekövetkezést.
A táblázatból leolvasható, hogy ha mind a három ok igaz, akkor az elsı és második okozat
is bekövetkezik. Abban az esetben, ha az elsı ok igaz a második pedig hamis, akkor a
harmadik feltétel nincs befolyással az eredmény alakulására.

36
Horváth László Szoftvertesztelés a gyakorlatban

1. teszteset 2. teszteset 3, 4. teszteset 5. teszteset 6. teszteset 7, 8. teszteset


Ok1 I I I H I H
Ok2 I I H I H H
Ok3 I H x I I x
Okozat1 P P P
Okozat2 P P
Okozat3 P P
Okozat4 P P

3. 7. táblázat. Egy döntési tábla részei

Amikor az okok mindegyike bináris jellegő akkor a döntési táblát korlátozott bemeneti
táblának nevezzük, míg ha többértékőek, akkor bıvített bemeneti táblázatról beszélünk.
A döntési tábla felépítésébıl adódóan automatikusan kialakul bennünk a teljesség érzése
az eljárással kapcsolatban.

3. 4. 3. Példa az ok-okozat gráfok és a döntési táblák együttes használatára

Az eljárás szemléltetéséhez az eddigiektıl eltérı példát használunk. A probléma a


következı: egy automata két karaktert vár a bemenetre, az elsı "a" vagy "b", a második pedig
egy szám. Amennyiben az elsı karakter helytelen a visszatérési érték „Hiba1”, ha pedig a
második karakter nem szám, akkor „Hiba2” (a kiértékelés „lazy” típusú).
A gráf elkészítéséhez elıször számozással kell ellátni a feltételeket. A problémában
megfogalmazott bemeneti feltételek (okok) a következık:
• 1: az elsı bemeneti érték „a”
• 2: az elsı bemeneti érték „b”
• 3: a második bemeneti érték szám
• 12: az 1. és 2. feltétel diszjunkciója
Az okozatokat a három lehetséges kimeneti értékbıl kaphatjuk meg:
• 70: mindkét bemeneti érték az elvártnak megfelelı
• 71: a visszatérési érték „Hiba1”

37
Horváth László Szoftvertesztelés a gyakorlatban

• 72: a visszatérési érték „Hiba2”


Most, hogy tudjuk melyek az okok és okozatok (hatások) a feladatban, elkészíthetjük a
hozzá kapcsolódó ok-okozat gráfot is.

1 71

E V 12
2
^ 70

3 ~ 72

3. 9. ábra. Az automata ok-okozat gráfja

Az ábrán megfigyelhetı egy új jelölés, az „E” betővel ellátott csúcs. A gráfban


feltüntethetünk bizonyos kiegészítı megszorításokat is. Összesen ötféle megszorítás jelölésére
van lehetıség az ok-okozat gráfok esetében (tegyük fel, hogy az ábrához hasonlóan 1-es és a
2-es feltételek közötti viszonyra teszünk megszorítást):
• E: 1 és 2 közül legfeljebb az egyik lehet igaz
• O: egy és csak egy feltétel lehet igaz
• I: legalább az egyiknek igaznak kell lenni
• R: megköveteljük, hogy ha az egyik igaz a másiknak is igaznak kell lennie
• M: maszk, vagyis ha 1-es igaz, akkor 2-esnek hamisnak kell lenni

Miután elkészültünk az ok-okozat gráffal, nekiláthatunk a döntési tábla elkészítésének. A


táblázatnak annyi sora lesz amennyi a gráfban szereplı csúcsok száma, jelen esetben ez hat
sort jelent (3. 8. táblázat).
Felmerülhet a kérdés, hogy miért négy teszteset van, ahelyett, hogy csak három lenne?
Nos a 70-es állapotba kétféle módon is eljuthatunk, ha úgy tetszik két független út, vezet
hozzá. Elsı esetben az elsı input értéke „a”, míg a második esetben „b”. Természetesen
mindkét esetet le kell tesztelni.
Megvizsgálva a módszer hatékonyságát láthatjuk, hogy az eredeti 23 = 8 teszteset helyett,
mindössze 4 tesztesettel elvégezhetı a tesztelés. Minél nagyobb egy gráf, annál nagyobb a
nyereség is.

38
Horváth László Szoftvertesztelés a gyakorlatban

Teszt1 Teszt2 Teszt3 Teszt4


1 H x I H
2 H x H I
3 X H I I
71 P
72 P
70 P P

3. 8. táblázat. Döntési tábla az automatához

3. 5. A funkcionális tesztelés áttekintése

Az elızı fejezetekben sok különféle technikát megvizsgáltunk a funkcionális tesztelés


témakörébıl. A közös ezekben az, hogy mindegyik eljárás úgy tekint a programra, mint
egyfajta matematikai függvényre, ami megfeleltetést hoz létre a bemeneti és kimeneti értékek
között.
Az ekvivalencia osztályozás során megpróbáltuk a bemeneti értékeket közelebbrıl
megvizsgálni annak érdekében, hogy osztályokba sorolhassuk ıket. Négy fajtája használatos
az ekvivalencia osztályozásnak – a gyenge normál, erıs normál, gyenge robusztus, valamit az
erıs robusztus. Az ekvivalencia osztályozás célja, hogy csökkentsük a szükséges tesztesetek
számát.
A határérték vizsgálattal való megközelítés esetén a teszteseteket a bemeneti tartományok
határai határozzák meg, ily módon négy különbözı technikához jutunk – határérték analízis,
robusztusság tesztelés, legrosszabb eset tesztelés, robusztus legrosszabb eset tesztelés.
Végül szót ejtettünk a döntési tábla használatáról, amihez meg kell vizsgálni a feladatban
szereplı változók között fennálló logikai kapcsolatokat.

3. 5. 1. Mit használjunk?

A gyakorlatban mindig a feladathoz igazodva magunknak kell kiválasztani a megfelelı


technikát. A tartomány elemzésén alapuló eljárások semmilyen módon nem érzékenyek a
változók közötti logikai kapcsolatokra, és viszonylag mechanikusan elvégezhetıek. Az
osztályozásnál csak annyi szükséges, hogy megállapítsuk az ekvivalencia osztályozás

39
Horváth László Szoftvertesztelés a gyakorlatban

feltételeit, és onnantól a tesztelés jól automatizálhatóvá válik. A határérték tesztelés esetében


még könnyebb dolgunk van, hiszen csak a bemeneti értékek tartományait kell meghatározni
és kezdıdhet is a tesztelés, egy elıre meghatározott séma segítségével. Itt könnyen
kiszámolható elıre a szükséges tesztesetek száma is, tovább növelve a bizalmat a tesztelés
teljességével kapcsolatban. A technikák közül az ok-okozat gráfok és a velük szoros
kapcsolatban lévı döntési táblák használata a legösszetettebb feladat. Megköveteli a
tesztelıtıl, hogy figyelembe vegye a programban található logikai és adat kapcsolatokat. Ha
ezeket sikeresen megállapítottuk, akkor egy teljes és minimális tesztkészletet kapunk.
Ahhoz hogy könnyebben kiválasszuk a számunkra legmegfelelıbb technikát, fel kell
tennünk magunknak néhány kérdést:
• A változók fizikai mennyiségeket reprezentálnak?
• Van valamilyen kapcsolat, függıség a változók között?
• Egyszerő vagy összetett hiba elıfordulás lehetséges?
• Mennyire fontos a hibakezelés?

Ha a fenti kérdésekre tisztáztuk a választ, akkor a következı táblázat segítségével talán kicsit
egyszerőbbé válik a megfelelı technika kiválasztása. A táblázat maga is egy döntési tábla,
hiszen szoros összefüggés van a megfogalmazott kérdések és az alkalmazható eljárások
között.

c1 Változók típusa (f: fizikai, l: logikai)? f f f f f l l l l l


c2 Függetlenek a változók? i i i i n i i i i n
c3 Egyszerő hiba elıfordulás? i i n n - i i n n -
c4 Hibakezelés? i n i n - i n i n -
a1 Határérték analízis x
a2 Robusztusság tesztelés x
a3 Legrosszabb eset tesztelés x
a4 Robusztus legrosszabb eset tesztelés x
a5 Gyenge ekvivalencia osztályozás x x x x
a6 Erıs ekvivalencia osztályozás x x x x x x
a7 Döntési tábla x x

3. 9. táblázat. Tesztelési technika kiválasztását megkönnyítı táblázat

40
Horváth László Szoftvertesztelés a gyakorlatban

Végül megemlítjük, hogy a gyakorlatban használatos még a véletlenszerő tesztelés is. Ez a


tesztelés, akkor lehet hasznos, ha nagy tömegben van szükségünk tesztesetekre. A
determinisztikus tervezési hibák felfedhetıek ugyan vele, azonban hibafelfedési képessége
nagy mértékben korlátozott.

41
Horváth László Szoftvertesztelés a gyakorlatban

4. Strukturális tesztelés
A strukturális tesztelési technikák legfıbb megkülönböztetı jegye, hogy mind a
tesztelendı program kódjának elemzésén alapulnak. A tesztelés célja a kód maximális
lefedése. A következı három fejezetben megvizsgáljuk az útvonal tesztelés két fı módját,
valamint az adatáram alapú tesztelést.

4. 1. Útvonal tesztelés

Adott egy szoftver valamely programnyelven implementálva, továbbá a hozzá tartozó


program gráf, amely egy olyan irányított gráf, amelyben a csúcsok állapot részletek, az élek
pedig a vezérlés és adatáramlás irányát jelzik. Tegyük fel, hogy i és j a gráf két csúcsa. Él
vezet az i. csúcsból a j. csúcsba, ha a j. csúcshoz tartozó állapot közvetlenül elérhetı az i. -hez
tartozó állapotból.
A program gráf megkonstruálása egy konkrét programhoz egyszerő folyamat. Ezt a
folyamatot a korábban ismertetett háromszög probléma pszeudo-kódja segítségével mutatjuk
be. A sorok számai állapotokat jelölnek. Ezen a ponton eldönthetı, hogy minden egyes állapot
részletet külön számmal látunk el, vagy néhány egyszerőbb állapotot összevonunk egy szám
alá. Más részrıl különbséget tehetnénk a végrehajtható és nem végrehajtható állapotok között.
Utóbbiak közé tartoznak a változó és típus deklarációk. Itt most ettıl eltekintünk, viszont a
gráfban nem mindig jelöljük ezeket a csúcsokat.

1. Program HAROMSZOG
2. Dim a, b, c As Integer
3. Dim Haromszoge As Boolean
1. lépés: adatok beolvasása
4. Output(„Adjon meg 3 egész számot, amelyek a háromszög oldalai lesznek!”)
5. Input(a, b, c)
6. Output(„A oldal hossza:”,a)
7. Output(„B oldal hossza:”,b)
8. Output(„C oldal hossza:”,c)
2. lépés: alkothat-e háromszöget a három megadott oldal
9. If(a<b + c) AND (b<a + c) AND (c<a + b)

42
Horváth László Szoftvertesztelés a gyakorlatban

10. Then Haromszoge = true


11. Else Haromszoge = false
12. EndIf
3. lépés: háromszög típusának megállapítása
13. If Haromszoge
14. Then If(a = b) AND (b=c)
15. Then Output(„Egyenlı oldalú háromszög”)
16. Else If(a ≠ b) AND (a ≠ c) AND (b ≠ c)
17. Then Output(„Általános háromszög”)
18. Else Output(„Egyenlı szárú háromszög”)
19. EndIf
20. EndIf
21. Else Output(„Nem háromszög”)
22. EndIf
23. End HAROMSZOG

A fenti programhoz tartozó gráf a 4. 1. ábrán látható. A 4.-tıl kezdve egészen a 8.-ig a
csúcsok egy sorozatot alkotnak. Ezután a 9-es és 12-es csúcsok között egy if-then-else
elágazás szerkezet jelölése látható. Hasonlóan a 13-tól 22-ig csúcsok is egymásba ágyazott
elágazások sorozatai. A 4-es és 23-as csúcsok a program be- és kilépı állapotai. Az eljárás
ciklusmentes, így az elkészített gráf irányított, körmentes gráf lesz.
A program gráfok fontossága abban áll, hogy a program végrehajtása során utakat jelöl ki
a gráf bevezetı csúcsától a kivezetı csúcsig. A tesztesetek készítése során éppen az lesz a
feladat, hogy valamiféle kapcsolatot hozzunk létre a gráfban található független utak és a
program végrehajtása között. Rendelkezésünkre áll egy elegáns elméleti módszer, amelynek
segítségével a potenciálisan végtelen számú végrehajtási utak számát, kiválasztva a
számunkra érdekeseket. A 4. 2. – es ábrán egy nagyon szemléletes példát látunk arra, hogy
miért nem lehetséges a teljes és kimerítı útvonal tesztelése egy programnak. Az ábrán látható,
hogy 3 különbözı út vezet a B csúcsból az F csúcsba, egy ciklus belsejében. Ha a ciklus csak
18 –szor fut le, akkor is milliárdos nagyságrendő végrehajtási út létezik.

43
Horváth László Szoftvertesztelés a gyakorlatban

4 5 6 7 8

10 11

12

13
21 14
15 16

17 18

19

20

22

23

4. 1. ábra. A háromszög probléma program gráfja

In

C D E

Out

4. 2. ábra. Utak milliárdjai jöhetnek létre a végrehajtás során

44
Horváth László Szoftvertesztelés a gyakorlatban

4. 1. 1. DD - utak

A legismertebb útvonal tesztelési módszer egy döntés a döntéshez (decision-to-decision)


útvonal készítésén alapul. A név állapotok sorozatára utal, ahol az egyik állapot kivezetı
pontjából indul a következı állapot. Egy ilyen sorozatban nincsenek elágazások, így az
összetartozó kódok dominó módjára viselkednek. Ha ez egyik lefut, a többi is le kell, hogy
fusson. Az eredeti definíció második generációs nyelvekre igaz (pl.: FORTRAN II). Ezeknél a
döntési kényszert reprezentáló állapotok, mint amilyen az aritmetikus elágazás vagy a DO
ciklus, címkéket használnak a célállapot kijelölésére. Az olyan blokk struktúrált nyelvek
esetében, mint a Pascal, az Ada, vagy a C ez a definíció már nem egészen helyénvaló.
A DD - utakat egy irányított gráf csúcsainak segítségével fogjuk definiálni. Ezeket az
utakat láncoknak is nevezzük, ahol a lánc egy olyan út amelynek kezdı és befejezı csúcsa
különbözik egymástól, és minden belsı csúcsnak a be és kimenı foka is 1. A 4. 3.-as ábrán
láthatunk példát egy láncra.

Kezdı Belsı Befejezı


csúcs csúcsok csúcs

4. 3. ábra. Csúcsok egy lánca egy irányított gráfban

A DD - út egy lánc egy program gráfjában, ami:


• 1. eset: Egyetlen csúcsból áll, amelynek bemenı foka 0
• 2. eset: Egyetlen csúcsból áll, amelynek kimenı foka 0
• 3. eset: Egyetlen csúcsból áll, a bemenı foka≥ 2, vagy a kimenı foka≥ 2
• 4. eset: Egyetlen csúcsból áll 1 kimenı éllel és 1 bemenı éllel
• 5. eset: maximális lánc ≥1 hosszúsággal

Az elsı és második eset biztosítja a program gráfjának be és kimeneti pontjának egyediségét,


mint kezdeti és befejezı DD - utakat. A harmadik eset az összetett csúcsokkal foglalkozik és
biztosítja, hogy egyetlen csúcs se szerepelhessen egynél több DD – úton. A negyedik esetre a
rövid ágak miatt van szükség, megtartva az egy állapot részlet egy DD – út alapelvet. Az

45
Horváth László Szoftvertesztelés a gyakorlatban

ötödik eset a normál eset, ahol a lánc csúcsok sorozata egyetlen bemenettel és kimenettel. Ez
egy igen összetett definíció, amelyet a 4. 1. ábrán látott gráf segítségével szemléltetünk. A 4 –
el címkézett csúcs egy példa az elsı esetnek megfelelı DD – útra (nevezzük ezt elsınek). A
23-as csúcs lehet példa a második esetre (nevezzük utolsónak). Az 5-tıl 8-ig élek pedig
megfelelnek az ötödik esetnek. Tudjuk, hogy ennek a DD – útnak az utolsó eleme a 8-as
csúcs, mert ez az utolsó csúcs, ami kielégíti a két kapcsolat feltételét. Ha a lánchoz
hozzávennénk a 9-es csúcsot is, akkor megsértenénk a bemenı fok = kimenı fok = 1 feltételt.
Ha megállunk a 7-es csúcsnál, akkor viszont a maximalitás kritériumát sértenénk meg. A 10,
11, 15, 17, 18 és 21-es csúcsok megfelelnek a negyedik esetben foglaltaknak. A 9, 12, 13, 14,
16, 19, 20 és 22-es csúcsok példaként szolgálnak a harmadik esetre. Szokás a gráfban szereplı
DD – utakat elnevezni az ABC nagy betőivel. A példa alapján megállapítható, hogy a
háromszög probléma egy logikailag összetett, ugyanakkor kis számítási igénnyel rendelkezı
feladat. Ez a fajta kombináció sok, rövid DD – utat eredményez.
Tegyük fel, hogy adott egy feladat implementációja. A hozzá tartozó DD – út gráf egy
olyan gráf, amelynek csúcsai DD – utak a program gráfjából, az élek pedig a DD – utak
közötti vezérlés folyamát mutatják. Valójában a DD – út gráf nem más, mint egyfajta gráf
tömörítés, ahol bizonyos csúcsokat a program gráfból (a láncokat) összevonunk egy csúcsba.
Ez a fajta összevonás és átalakítás nem okoz problémát a tesztelık számára, mert ma már
rendelkezésre állnak olyan programok, amelyek segítségével elkészíthetı egy program DD –
út gráfja. A gyakorlatban 100 sornál hosszabb forráskódú eljárásokhoz segédeszközt
használnak a DD – út gráfok elkészítéséhez.

4. 2. Lefedettség metrikák

A DD – utak létjogosultságát az adja, hogy nagyon pontos információval szolgálnak a


teszt lefedettséggel kapcsolatban. Emlékkezünk rá, hogy a funkcionális tesztelés alapvetı
korlátja volt, hogy lehetetlen volt megmondani a tesztkészlet miféle hiányosságokat hagy,
vagy mekkora redundanciát okoz a végrehajtásban. Ha visszaemlékszünk korábban a 2.
fejezetben szerepelt egy Venn diagramm arról, hogy milyen kapcsolatban áll egymással a
programozott és az elvárt viselkedés, valamint a tesztelt programrészek (2. 2. ábra). A teszt
lefedettség metrikák egy eszközt szolgáltatnak annak mérésére, hogy a tesztesetek halmaza
milyen mértékben fedi le a programot.

46
Horváth László Szoftvertesztelés a gyakorlatban

Számos tesztelési metrika létezik, amelyek közül a legalapvetıbbeket láthatjuk a 4. 1.


táblázatban.

Metrika Lefedettség
C0 Minden utasítás
C1 Minden DD – út
C1p Minden predikátum minden kimenethez
C2 C1 lefedettsége + ciklus lefedés
Cd C1 lefedettsége + függı DD – út párok
CMCC Többszörös feltételek lefedése
Cik Minden program végrehajtási út k számú ciklusismétlésig (ez általában k = 2)
C∞ Minden lehetséges végrehajtási út

4. 1. táblázat. Strukturális teszt lefedettség metrikák

A program lefedettségének ismeretében érezhetıen irányíthatóbbá válik a tesztelés


folyamata. Manapság minden jól szervezett cég a C1 metrikát alkalmazza. Tapasztalatok
alapján ennek a metrikának a segítségével a hibák 85%-a deríthetı fel. Az utasítás alapú
lefedettség is széles körben használatos (az Amerikai Nemzeti Szabványügyi Intézet - ANSI
standardként fogadta el 187B szám alatt, és az IBM széles körben alkalmazza az 1970-es évek
közepe óta).

4. 2. 1. Metrika alapú tesztelés

A 4. 1.-es táblázatban szereplı metrikák megmutatják számunkra mit kell tesztelni,


azonban nem derül ki, milyen módon. Ebben a fejezetben közelebbrıl megvizsgáljuk azokat a
technikákat, amelyek a kód felhasználásával végzik a tesztelést. Szem elıtt kell tartanunk egy
fontos dolgot: a lefedettség metrikái olyan program gráfokon alapulnak, amelyekben a
csúcsok teljes állapotokat jelölnek, habár a mi technikáink megengedik rész állapotok
használatát.

47
Horváth László Szoftvertesztelés a gyakorlatban

Utasítás és állapot tesztelés

Az általunk használt formalizmus miatt, amelyben állapot részleteket jelöltünk a program


gráfjában a csúcsokkal, az utasítások és állapotok szintjén (C0 és C1) össze kell vonni a
csúcsokat egy állapotba. A háromszög problémában (4. 1. ábra) a 9, 10, 11 és 12-es csúcsok
egyetlen if-then-else vezérlési szerkezetet alkotnak. Ha megköveteljük, hogy a csúcsok teljes
állapotoknak feleljenek meg, akkor csak egy döntési lehetıséget tudunk kiértékelni, így téve
eleget a lefedettség kritériumának. Mivel mi részállapotokat is megengedtünk, természetesen
egy ilyen állapot három különbözı csúcs létrejöttét eredményezi. Akár követjük a mi
formalizmusunkat, akár nem, ezek a fedettségi metrikák megkövetelik, hogy találjunk egy
olyan tesztkészletet, amelyet kiértékelve a gráf minden egyes csúcsán (állapotán) legalább
egyszer áthalad a vezérlés.

DD – út tesztelés

Amikor minden DD – út lefedésre került tudjuk, hogy valamennyi állítás kimenete


végrehajtódott. Ez lehetıvé teszi, hogy a gráfban (DD – út gráf, vagy program gráf) szereplı
valamennyi élet lefedjük, ellentétben azzal, hogy csak a csúcsokat fedjük le. Az if–then és az
if–then-else szerkezetek esetében ez azt jelenti, hogy mind az igaz, mind pedig a hamis ágat
lefedtük. A case utasítások esetében minden lehetıséget le kell fedni. Hasznos tudni mit kell
még tennünk, hogy teszteljünk egy DD – utat. A hosszabb DD – utak általában összetett
számításokat reprezentálnak, amelyeket mi jogosan független függvényeknek tartunk. Az
ilyen DD – utak esetében azonban ajánlatos és hasznos lehet olyan funkcionális tesztek
elvégzése is, mint a határérték analízis vagy a speciális értékekkel való tesztelés, így
biztosítva a tesztelés teljességét.

Függı DD – út párok

A Cd metrika a következı fejezetet (adatáram alapú tesztelés) vetíti elıre. A leggyakoribb


függıség a DD – utak között a definíció/referencia kapcsolat, ahol egy változót deklarálunk
az egyik DD – úton belül, majd hivatkozunk rá egy másikból. Ezeknek a kapcsolatoknak a
fontosságát az adja, hogy szorosan kötıdnek a lehetetlen utak problémájához. Az eddigiek

48
Horváth László Szoftvertesztelés a gyakorlatban

alapján remek példákat tudunk adni függı DD – utakra. A 4. 1.-es ábrán szereplı gráfban
ilyen párt alkot a 9-es és 11-es csúcs, vagy a 10-es és 13-as. Az egyszerő DD – út lefedés nem
értékeli ezeket a függıségeket, így a mélyebben rejlı hibákra nem derül fény.

Többszörös feltétel lefedés

Vizsgáljuk meg közelebbrıl a gráfban szereplı (4. 1. ábra) összetett feltételeket. Ha


elkészítjük a DD – út gráfját ennek a programnak akkor a 5-tıl 8-ig csúcsok egyetlen csúcsba
egyesülnek. Ha el akarunk jutni a 12-es csúcsba az 5-ös csúcsból, akkor át kell haladnunk egy
elágazáson. Ahelyett, hogy egyszerő lefedést alkalmaznánk, azaz megvizsgálnánk az
elıfeltételeket és a hozzájuk tartozó igaz, vagy hamis kimeneti értékeket, végig kell nézni az
összes lehetséges utat, amelyek elıállhatnak. Elsı lehetıség, ha készítünk egy igazság
táblázatot. Egy három részbıl álló összetett feltételhez 9 sor tartozna a táblázatban, ami pedig
9 tesztesetet jelent. Második lehetıségként újrakódolhatjuk a programot és szétszedhetjük az
összetett feltételt egyszerő if-the-else szerkezetek sorozatára. Ez azonban még több rövid DD
– út létrejöttét eredményezné. Egy érdekes problémával szembesültünk tehát: állapot
komplexitás szemben az utak komplexitásával.

Ciklus lefedés

A ciklusok tesztelése egy alaposan tanulmányozott és jó eredményekkel szolgáló


probléma. A ciklusokkal kapcsolatba hozható problémák száma igen magas, így nagy
kockázati tényezıként szerepelnek minden egyes szoftverben. A ciklusokat osztályokba lehet
sorolni.
Az elsı csoport az egyszerő ciklusoké. Ebben az esetben a tesztelés során le kell futtatni a
ciklust egyszer, kétszer, n maximum lefutás esetén m (<n) -szer, valamint n-1, n és n+1
alkalommal is.
A második csoportba tartoznak az egymásba ágyazott ciklusok. Az eljárás lényege itt az,
hogy mindig belülrıl kifelé kell végezni a tesztelést, és az egyes ciklusokat mindig
egyszerőként kell kezelni. Ha egy belsı ciklus tesztelésével végeztünk, akkor azt fix értékkel
kell futtatni (tipikus érték), míg a külsın végig kell futtatni az elızı bekezdésben olvasott
értékeket.

49
Horváth László Szoftvertesztelés a gyakorlatban

Konkatenált ciklusok esetén két eset fordulhat elı. Az elsı, hogy a két ciklus független
egymástól, ekkor az egyszerő esethez hasonlóan kell eljárni. A második esetben pedig
függıség áll fenn köztük, ekkor az egymásba ágyazott esetben leírtakat kell alkalmazni.

4. 2. 2. Teszt lefedettség elemzık

A lefedettség elemzık olyan eszközök, amelyek segítséget adnak a lefedettség méréséhez,


illetve a tesztkészlet teljességének megállapításában. A lefedettség elemzı segítségével a
tesztelı egy tesztkészletet futtat a tesztelésre váró programon, amelyet elızetesen
felinstrumentált. Az elemzı ezután egy lefedettség jelentést készít. A legtöbb esetben például
a DD – út fedettség vizsgálatához az instrumentálás során meg kell adni a programhoz az
azonosítókat és címkéket, amelyekkel dolgozunk. Amikor a felinstrumentált program
végrehajtásra kerül a tesztesetekkel, az elemzı minden egyes alkalommal táblázatba foglalja,
hogy melyik DD – utakat fedtük le a futás során. Így a tesztelı kísérletezhet a tesztkészletben
szereplı tesztesetek kiválasztásával, a maximális fedettség elérése érdekében.

4. 3. Bázis útvonaltesztelés

A matematikai elgondolás, ami a „bázis” mögött rejlik, nagyon vonzó lehetıségeket kínál
a strukturális tesztelésre. A matematikusok a bázis fogalmát általában egy vektortérnek
nevezett struktúra segítségével definiálják. A vektortér elemei a vektorok, amelyekre az
összeadás és szorzás mőveletek definiálva vannak. További fél tucat feltétel teljesülése esetén
megkapjuk a vektortér definícióját. Minden vektortérhez tartozik egy bázis (valójában több
bázis is tartozhat hozzájuk). Egy vektortér bázisa vektorok egy halmaza, amelyek függetlenek
egymástól és a vektortér bármelyik másik eleme elıállítható a segítségükkel.
A tesztelés lehetıségét rejti magában, ha a programra úgy tekintünk, mint egy vektortérre,
és egy ilyen vektortérre megkeressük a bázis elemeit. Ha a bázis elemei rendben vannak,
akkor feltételezhetjük, hogy minden, ami ezekbıl az elemekbıl származik, szintén rendben
lesz, és helyesen fog mőködni. Ebben a fejezetben megismerkedünk egy kicsit Thomas
McCabe ebben a témában folytatott munkájával.

50
Horváth László Szoftvertesztelés a gyakorlatban

4. 3. 1. McCabe bázis útvonaltesztelése

A 4. 4.-es ábrán látható egy rendezett gráf, amire programgráfként fogunk tekinteni. A
programnak egy bemenete van (A), tartalmaz egy ciklust (B, C) két lehetséges kilépési
ponttal, valamint egy elágazást (D, E, F). A kimeneti pont a G csúcs.

B D

C F

4. 4. ábra. McCabe vezérlési gráfja

McCabe elmélete a ciklomatikus komplexitáson alapul. Egy erısen összefüggı gráf


ciklomatikus komplexitása megmutatja a gráfban lévı lineárisan független útvonalak számát.
Két útvonalat lineárisan függetlennek tekintünk, ha legalább egy élben eltérnek egymástól.
Bármikor létre tudunk hozni egy erısen összefüggı gráfot, ha a kimeneti csúcsból húzunk
egy élet a bemeneti csúcsba. Megjegyezzük, hogy ha az egyszerő bemenet - kimenet szabályát
megszegjük, nagyban megnövekszik a ciklomatikus komplexitás, mert minden kimenetet
össze kell kötni minden bemenettel.
Némi vita van a szakirodalomban azzal kapcsolatban, hogy mi a ciklomatikus komplexitás
számításának pontos módja. Néhány formula szerint C(G) = E – N + p, míg mások szerint az
E – N + 2p használatos. Abban mindenki megegyezik, hogy az E az élek, N a csúcsok számát
jelöli, p pedig az összekapcsolt komponensek számát jelöli. A vita kétségtelenül egy
tetszılegesen irányított gráf, erısen összefüggı gráffá konvertálásából ered (amilyen a 4. 5.
ábrán szerepel), amihez egy élet kell beszúrni a kimeneti pontból a forrás csúcsba. Egy él
hozzáadása nyilvánvalóan megváltoztatja a formula eredményét, azonban nincs hatással az
útvonalak számára.

51
Horváth László Szoftvertesztelés a gyakorlatban

A
1 2
B D
5 6
7
3 4 E
8
C F
9 10

4. 5. ábra. McCabe gráfjából származó erısen összefüggı gráf

A 4. 4. ábrán a lineárisan független utak száma a forrás csúcstól a kivezetı csúcsig:


C(G) = E – N +2p = 10 – 7 + 2*1 = 5.
A 4. 5.-ös ábrán látható gráfban pedig a lineárisan független útvonalak száma:
C(G) = E – N + p = 11 -7 + 1 = 5
A 4. 5. ábrán látható erısen összefüggı gráf ciklomatikus komplexitása 5, tehát öt
független útvonal található benne. Kis gráfok esetén szemmel is megállapíthatjuk melyek a
lineárisan független utak. A fenti példában szereplı független utak a következık:
P1: A, B, C, G
P2: A, B, C, B, C, G
P3: A, B, E, F, G
P4: A, D, E, F, G
P5: A, D, F, G

Hozzáláthatunk a vektortér definiálásához, amihez meg kell határoznunk az összeadás és a


skaláris szorzás mőveleteket. Két út összeadása jelentse azt, hogy egymás után főzzük az
utakat, a szorzás pedig utak ismétlését jelenti. Ezzel a formalizmussal McCabe eljutott a
program gráfokhoz tartozó vektorterekhez. A példa, amelyen keresztül illusztrálta az
adatszerkezethez tartozó bázist, hogy az A, B, C, B, E, F, G útvonal elıáll a P2 + P3 – P1
összeggel, míg az A, B, C, B, C, B, C, G úthoz tartozó lineáris kombináció a 2P2 – P1. Az
összeadás mővelete könnyen szemléltethetı egy táblázattal. A sorokban feltüntetjük az utakat,

52
Horváth László Szoftvertesztelés a gyakorlatban

az oszlopokat pedig az élekkel címkézzük. A 4. 2.-es táblázatban látható a példához tartozó


mátrix.

Utak / Lefedett élek 1 2 3 4 5 6 7 8 9 10


P1: A, B, C, G 1 0 0 1 0 0 0 0 1 0
P2: A, B, C, B, C, G 1 0 1 2 0 0 0 0 1 0
P3: A, B, E, F, G 1 0 0 0 1 0 0 1 0 1
P4: A, D, E, F, G 0 1 0 0 0 1 0 1 0 1
P5: A, D, F, G 0 1 0 0 0 0 1 0 0 1
Pl1: A, B, C, B, E, F, G 1 0 1 1 1 0 0 1 0 1
Pl2: A, B, C, B, C, B, C, G 1 0 2 3 0 0 0 0 1 0

4. 2. táblázat. Út/Él lefedettség

A sorok elején láthatók az utak nevei és hogy melyik csúcsokat foglalják magukban.
Ezután minden élhez feltüntetjük, hogy hányszor halad át rajta az út.
Könnyen ellenırizhetjük a P1-tıl P5-ig utak függetlenségét is. A vastag betős bejegyzések
jelzik azokat a csúcsokat, amelyekben eltérnek a P2 - P5 utak. A P1 út mindegyiktıl független,
hiszen bármelyik másikban találhatunk olyan éleket, amelyek szükségtelenek a P1 út
lefedéséhez. A bázist alkotó utak egyike sem törölhetı és ez az öt út kifeszíti a csúcsokból
létrehozható utak terét. A mátrixban feltüntettük az említett két példát is. Ha megvizsgáljuk az
éleikhez tartozó oszlopokat, szem elıtt tartva, hogyan definiáltuk az összeadást és a szorzást,
könnyen beláthatjuk, hogy valóban elıállíthatóak a megadott módon.
McCabe meghatározott egy módszert is, amelynek segítségével elıállítható a vektortérhez
tartozó bázis. Az eljárás egy alapvonal meghatározásával indul, ami összhangban van a
program egy átlagos végrehajtásával. Ennek kiválasztása némileg önkényesen történhet.
McCabe azt tanácsolja, hogy olyan utat keressünk, ami a lehetı legtöbb csúcsot foglalja
magában. Miután bejelöltük az alapvonalat, elindulunk az elsı csúcstól, és amint egy olyan
csúcshoz érünk, amelynek ≥2 kimenı éle van, a még le nem fedett élen haladunk tovább.
Lássuk McCabe példáját az eljárás szemléltetésére. Alapvonalként az A, B, C, B, E, F, G utat
választjuk. Az elsı hely ahol döntenünk kell az A csúcs, így az elsı bázisút létrehozásához a
2-es élet választjuk, az 1-es helyett. Így megkapjuk az A, D, E, F, G utat. Következı lépésben
ezt az utat követjük és a D csúcsnál a 7-es élen haladunk tovább. Az eredmény az A, D, F, G

53
Horváth László Szoftvertesztelés a gyakorlatban

út. Most már csak a B és C csúcsokat nem értékeltük ki. Ha ezt is megtesszük, megkapjuk a
hátralévı két báziselemet: A, B, E, F, G és A, B, C, G. Megjegyezzük, hogy a most elıállított
bázis utak halmaza nem egyezik meg a táblázatban szereplıvel, ami azonban nem okoz
problémát, hiszen nem követeltük meg a bázis egyértelmőségét, célunk csupán a független
utak egy maximális halmazának lefedése tesztekkel.

Vizsgálataink során, amiket a funkcionális teszteléssel kapcsolatban végeztünk,


észrevehettük hogy a tesztelés hézagos és redundáns volt, ami elfogadhatatlan. A probléma,
hogy a funkcionális tesztelés nagyon messze visz minket a program kódjától. Az útvonal
tesztelés során, némileg a másik véglethez kerültünk közel. A kódtól eljutottunk egyfajta gráf
reprezentációhoz és vizsgálatainkat ilyen gráfokon hajtottuk végre. A gráfok használatán
alapuló útvonal tesztelés során bizonyos metrikákat alkalmaztunk, amelyek segítségével
megoldást találtunk a redundancia problémájára. Ha egy olyan végrehajtási utat találunk,
amely egyszer már szerepelt, a hozzá tartozó tesztesetet kivehetjük a teszthalmazból, hiszen
biztosak lehetünk benne, hogy helyesen mőködik a program. A következı fejezetben, amikor
az adatáram alapú teszteléssel foglalkozunk, közelebb kerülünk majd a programkódhoz.

4. 4. Adatáram alapú tesztelés

Az adatáram egy eléggé szerencsétlen elnevezés, mert azt sugalmazza, hogy valamiféle
kapcsolatban áll az adatáram diagrammal, pedig semmilyen kapcsolat sincs köztük. A
strukturális tesztelésnek ez a módja azt vizsgálja, hogy a programban található változók közül
melyik kap értéket, és melyikre hivatkoznak. Látni fogjuk, hogy az adatáram alapú tesztelés
egyfajta ellenırzı funkciót is betölt az útvonaltesztelésekkel kapcsolatban. Sokan ezt a
tesztelési módot is az útvonaltesztelések közé sorolják.
Már az 1960-es évek óta vizsgálják a programozók a forráskódot abból a szempontból,
hogy melyik változók kapnak értéket, és ezek közül melyeket használjuk fel. A korai
adatáram alapú elemzések gyakran a hibák egy olyan halmazához vezettek, amit ma a
definiálás/referencia problémájaként ismerünk:
• egy változót definiáltuk, de nem hivatkozunk rá
• egy változót használunk de nem definiáltuk
• egy változót kétszer definiálunk használat elıtt.

54
Horváth László Szoftvertesztelés a gyakorlatban

A következıkben ismertetünk néhány tesztelési kritériumot, amelyek a Rapps-Weyuker


kritérium-családba tartoznak. Felhasználjuk a du pár fogalmát, ami nem más, mint olyan
összetartozó kódsor párok a programkódban ahol az elsıben definiált változót a másodikban
felhasználjuk, valamint továbbra is szükségünk lesz a program gráf fogalmára.

Minden definíció kritérium

A minden definíció tesztelési kritérium szerint a program minden egyes di definíciójának


legalább egy felhasználását tesztelni kell, azaz a definíciókhoz tartozó, egy tetszıleges du-
párt. Az alábbi egyszerő példa esetén az y=1 program input mind az x=1, mind pedig read(y)
definíciók egy felhasználását (y=y+x) végrehajtja, ezért ezen egyetlen elemő teszthalmaz
teljesíti a minden definíció kritériumot.
1. read (y);
2. x = 1;
3. if y > 0 then
4. y = y + x;
5. else
6. y = y - x;
7. endif;
8. write (y);
Megjegyezzük, hogy a minden definíció kritérium nem teljesíti a minimálisnak tekinthetı
minden-él kritériumot, ezért ez nem tekinthetı a gyakorlatban elfogadható tesztelésnek.

Minden-felhasználás kritérium

A minden-felhasználás tesztelési kritérium megköveteli, hogy minden egyes definíció-


felhasználás párt hajtsuk végre, továbbá, ha a du-pár felhasználása egy predikátumban van,
akkor a predikátumnak megfelelı csomópontból kiinduló minden élt tesztelnünk kell.
Az elıbbi példában az y=1, és az y=0 program inputokból alkotott teszthalmaz teljesíti a
minden-felhasználás kritériumot, hiszen az x=1, read(y) definíciók minden felhasználását (if
y>0, y=y+x, y=y-x), továbbá az if y>0 predikátum mindkét ágát leteszteljük.

55
Horváth László Szoftvertesztelés a gyakorlatban

Minden c - felhasználás/néhány p - felhasználás

Elıször is tisztáznunk kell két fogalmat, ami ahhoz szükséges, hogy a kritériumot
megfogalmazhassuk.
• Definíció1: Egy felhasználást predikátum (“predicate”) felhasználásnak nevezünk
(“p - use”), ha a felhasználás egy feltételes utasításban szerepel. Például az if x>0
utasítás az x változó egy p - felhasználásának számít.
• Definíció2: Egy felhasználás számítási (“computation”) felhasználás (“c - use”), ha
nem predikátum felhasználás Például az „...=y+2” egy c - felhasználás y-ra nézve.
A minden c - felhasználás/néhány p - felhasználás kritérium megköveteli, hogy egy
definíció minden c - felhasználását le kell tesztelni, továbbá, ha egy definíciónak nincsen
számítási felhasználása, akkor ennek legalább egy predikátumbeli felhasználását végre kell
hajtani legalább egy teszteset segítségével.
Az iménti példa esetén az y=1 és az y=0 program inputokból alkotott halmaz teljesíti a
minden c - felhasználás/néhány p - felhasználás kritériumot, hiszen az x=1, read(y) definíciók
minden számítási felhasználását (y=y+x, y=y-x), továbbá a read(y) if y>0 predikátumbeli
felhasználását leteszteljük.

Minden p - felhasználás/néhány c - felhasználás

A minden p - felhasználás/néhány c - felhasználás kritérium megköveteli, hogy egy


definíció minden p - felhasználását, és a predikátumok csomópontjaiból kiinduló minden ágat
le kell tesztelni, illetve ha egy definíciónak nincsen predikátum felhasználása, akkor ennek
legalább egy számítási felhasználását végre kell hajtani legalább egy teszteset által.
Az alábbi példa esetén az x=1 definícióhoz tartozó x>0 és x>100 predikátum
felhasználásokat is tesztelni kell, nem elegendı az x>0 felhasználás végrehajtása.
1. x = 1;
2. if x > 0 then
3. if x > 100 then
4. ...
5. endif;
6. else

56
Horváth László Szoftvertesztelés a gyakorlatban

7. ...
8. endif;

Minden-definíció-felhasználás-út

A minden definíció-felhasználás út kritérium megköveteli minden definíció-felhasználás


tesztelését úgy, hogy a definíció és felhasználás csomópontjai közötti minden ciklusmentes
utat is tesztelnünk kell.
Az alábbi példa esetén, ha a kiválasztott du - pár a read(y), write(y), akkor az if x>0
feltételes utasítás mindkét ágát végre kell hajtani.
1. read (y);
2. if x > 0 then
3. ...
4. else
5. ...
6. endif;
7. write(y)

Alkalmazható kritérium család

Az adatáram alapú tesztelés nyilvánvalóan olyan programok esetében alkalmazható jó


eredménnyel, amelyek bonyolult számítási algoritmusokat tartalmaznak. Az ismertetett
kritériumok nagy hátránya, hogy nem foglalkoznak azzal, hogy egy definíció felhasználás
páros egyáltalán végrehajtható-e, azaz van-e olyan futtatható programút, amely tartalmazza a
du-párt. Ezért Frankl és Weyuker a kritériumok ún. alkalmazható változataként csak a
végrehajtható definíció-felhasználás párok tesztelését követelik meg. A gyakorlatban tehát az
adatáram alapú teszteléshez tartozó tesztkészlet részhalmaza a fent definiált kritériumok által
meghatározottnak.

57
Horváth László Szoftvertesztelés a gyakorlatban

4. 5. A strukturális tesztelés áttekintése

A strukturális tesztelés, vagy fehér doboz tesztelés során feltételeztük, hogy a tesztelınek
lehetısége van a kód vizsgálatára. A program forráskódja alapján bevezettük a program gráf
fogalmát és ehhez kapcsolódóan egy sor technikát ismertettünk, amelyek mind azt a célt
szolgálják, hogy növeljük a szoftverrel szembeni bizalmat. A fejezetben elıször ismertettük
az útvonal tesztelést, amihez szorosan kötıdött a DD – utak fogalma. Ezután néhány
szoftvertesztelési metrikával és azok használatával ismerkedtünk meg, majd ezeket követte
McCabe módszerének leírása a bázis útvonaltesztelésrıl. Végül bepillantást nyerhettünk az
adatáram alapú tesztelési kritériumok világába is.
A strukturális teszteléssel a programozói hibák könnyen felismerhetıek, hiszen a kód
nyitott könyvként szerepel elıttünk. Hátránya viszont a technikának, hogy a hiányos vagy
hibás szoftverspecifikációt nem ismeri fel. Nem detektálja továbbá a specifikációban
megfogalmazott, de nem implementált függvények hiányát sem. Korábban láthattuk a
funkcionális tesztelési módszerek hátrányait is és könnyen megállapítható, hogy egyik
módszer sem képes önmagában minden hibát felfedni. Még azt sem lehet mondani, hogy az
egyik sokkal hatékonyabb lenne a másiknál. Egymás kiegészítıi és mindig az alkalomhoz
mérten kell kiválasztani a számunkra legmegfelelıbbet. Általában azonban jó tanácsként
érdemes megfogadni, hogy mindig a funkcionális tesztekkel indítsunk, és utána mélyedjünk el
a kód elemzésében és a strukturális tesztek elvégzésében.
Mostanra felmerülhetett bennünk a kérdés, hogy vajon mikor kell abbahagyni a tesztelést,
illetve meddig érdemes folytatni? Nos erre több válasz is adható attól függıen, hogy mennyi
erıforrás áll rendelkezésünkre, illetve, hogy mik az elvárásaink a teszteléssel kapcsolatban.
Íme néhány lehetséges válasz a kérdésre:
1. Ha kifutottunk az idıbıl.
2. Ha a további tesztelés nem okoz újabb failure-öket.
3. Ha a további tesztelés nem tár fel újabb fault-okat.
4. Amikor nem tudunk kitalálni újabb teszteseteket.
5. Ha elértük a kívánt lefedettség szintet.
6. Amikor az összes hibát eltávolítottuk.

58
Horváth László Szoftvertesztelés a gyakorlatban

Sajnos az elsı válasz túl általános és a hatodik egyáltalán nem garantálható. A legtöbb
szoftver megbízhatósági modell a második és harmadik feltételt tekinti mérvadónak. Ezeket a
gyakorlatban is nagy sikerrel alkalmazzák. A negyedik feltétel is viszonylag hasznos lehet,
amennyiben követjük az ismertetett eljárásokat. Azonban ha híján vagyunk a motivációnak,
akkor ez a feltétel is hasztalanná válik. Az ötödik feltétel arra az esetre vonatkozik, hogy ha a
tesztelés során a feltárt hibák száma elkezd rohamosan csökkeni és a ráfordított költségek
meghaladják a hasznot. Amennyiben biztosak vagyunk benne, hogy nem maradtak nagy
veszélyt jelentı hibák a rendszerben akkor abbahagyhatjuk a tesztelést. Ha sikerült
megadnunk egy maximális lefedését a program gráfjában lévı független utaknak, akkor
szintén befejezhetjük a tesztelést, erre vonatkozik a hatodik feltétel. Az, hogy ki melyik
feltételt tekinti mérvadónak személy, vállalat, illetve alkalmazásfüggı dolog. Olyan
rendszerek esetében, ahol emberéletek, vagy nagy értékő felszerelés kerülhet veszélybe a
helytelen mőködés miatt, minél inkább törekedni kell az utolsó pont teljesítésére.
A következıkben eltávolodunk a szoftver szerkezeti elemeitıl és a kódtól és bemutatjuk a
felhasználói interfészek tesztelésére vonatkozó alapelveket, valamint foglalkozunk a
napjainkban egyre fontosabb objektum orientált tesztelést érintı problémákkal.

59
Horváth László Szoftvertesztelés a gyakorlatban

5. A Grafikus felhasználói interfész tesztelése

A mai alkalmazások szinte kivétel nélkül megkövetelik, hogy készüljön hozzájuk egy
felhasználói interfész, amelyen keresztül használatuk és karbantartásuk könnyebbé,
kezelhetıbbé válik. A kliens/szerver rendszerek esetében például egy átlagos felhasználó csak
az interfészen keresztül kerül kapcsolatba a rendszerrel, így annak minıségébıl tud csak
következtetést levonni a teljes rendszerrel kapcsolatban. Egy szoftverrendszer tesztelése során
a tesztelıknek meg kell birkózniuk a felület mőködéséhez szükséges függvények tesztelésével
is. A korábbi fejezetekben láthattuk, hogy egy alkalmazás input és output tartománya
lényegében végtelen lehet. A hibalehetıségek számát és a programhoz tartozó gráf
bonyolultságát csak tovább növelik a felhasználói interfész elemei.
A témával foglalkozó szakirodalomban újabban hajlamosak abba az irányba elmenni,
hogy csupán a felület tesztelését segítı eszközöket ismertetik, a mögöttes elvi tartalmat
mellızve. Itt megpróbálunk bemutatni egyfajta folyamatot, ami mentén a tesztelés elvégzése
és a hibák felfedése könnyebbé válik.

5. 1. A grafikus felhasználói interfész (GUI) sajátosságai

Manapság a grafikai interfészek széles körben kiszorították a hagyományos form alapú


technikákat. Íme néhány ok, miért érdemes GUI-t használni:
• A hagyományos kliens operációs rendszerben megszokott környezetet biztosít.
• A flexibilitás miatt sokféle környezetben és alkalmazásban használható.
• Nem észrevehetı átmenetet és kapcsolatot biztosít az elıre meghatározott és az
egyedileg készített alkalmazásrészek között.
• A felhasználónak lehetısége van mind az egér, mind pedig a billentyőzet
használatára.
• A felhasználó egy sokkal természetesebb környezetet kap az alkalmazáshoz, így a
mőködés megértése könnyebbé válik.
• Sokkal jobban kontrollálhatóvá válik az alkalmazás, mivel a felhasználó által
meghatározott sorrendben tőnnek fel és el az ablakok.

60
Horváth László Szoftvertesztelés a gyakorlatban

A hagyományos form alapú alkalmazás esetén a formok egy elıre meghatározott


sorrendben vannak elhelyezve. Általában egy menübıl választhatunk ki egy opciót, majd
megjelenik a hozzá tartozó képernyı. Az ilyen alkalmazásoknál egy jól megfigyelhetı
hierarchia kerül kialakításra a szintek között. Ha egy mezı elıtőnik, akkor lehetıség van
újabbak kiválasztására. Egy kétszintő menürendszer esetében, ami ötven opciót tartalmaz
menünként ez közel kétszáz különbözı képernyıt jelent. Formok esetében, ha egy opciót
meghívtunk, akkor csak az ehhez tartozó egyetlen formmal tudunk dolgozni. Ha egy újat
jelenítünk meg, az felülírja az elızıt, így a korábbi információk elvesznek számunkra.
Általában a formon szereplı mezık közötti navigálás sorrendje is kötött. Amíg egy mezıt
nem töltöttünk ki nem tudunk másikra állni.
A grafikus felhasználói felület esetén az elsı és legfontosabb dolog, hogy egy idıben több
ablak is nyitva lehet, és egyszerre tudunk dolgozni rajtuk. Minden ablak egy alkalmazáshoz
tartozik, és egyidejőleg több alkalmazást is futtathatunk. Az egér és különféle gyorsgombok
segítségével a munka könnyebbé és hatékonyabbá válik. A GUI segítségével a felhasználó
maga határozhatja meg, mely ablak legyen az elıtérben, és melyik a háttérben, szemben a
formokkal, ahol ez a programozó feladata. A GUI használata esetén tehát egyfajta
szabadságot biztosítunk a felhasználónak a navigáció, a rendszer funkciók elérése és
használata során.

5. 2. Néhány nehézség a teszteléssel kapcsolatban

A felhasználói interfész segítségével könnyebbé válik a fejlesztık számára a felület


megtervezése és kivitelezése. Minden alkalmazás nagyon hasonlóvá válik a többihez,
megkönnyítve így a szoftver alkalmazásának tanulását is. Ha azonban tesztelni kell egy ilyen
alkalmazást, akkor a háttérben megbújó összetettség nehézségeket okozhat.

Eseményvezérelt alkalmazás

Az interfészek esemény vezéreltsége okozza az elsı problémát a tesztelık számára. Mivel


a felhasználónak lehetısége van a felületen bárhova kattintani, így a kiváltható események
száma óriási méreteket ölt. Arra is lehetıség van, hogy takarásba hozzanak egy felületet egy
másikkal, ami tovább bonyolítja a dolgot, hiszen azt is figyelni kell, hogy éppen melyik az

61
Horváth László Szoftvertesztelés a gyakorlatban

aktív. A lehetıségek nagy száma megkívánja a kódtól, hogy helyesen kezelje a következı
lépést, bármi legyen is az. A legtöbb esetben ezek az események a háttérben, rendszerszinten
is kezelhetıek, néha azonban a programozóknak maguknak kell ezeket elkészíteni. Sok hiba
forrása lehet, ha nem megfelelıen gondoljuk végig a lehetıségeket, és nem készítünk
megfelelı kezelıfüggvényeket.

Nem várt események

A nem várt események problémát jelentenek a programozóknak és a tesztelıknek


egyaránt. Egy ilyen eseményre lehet példa, amikor a nyomtató kikapcsol, és feltőnik egy
ablak a képernyın, hogy tegyünk papírt a tartóba. Egy másik példa, ha egy adatbáziskezelı
rendszerben figyelmeztetı ablak jelenik meg, mert elfelejtettük elmenteni a módosításokat.
Ilyen és ehhez hasonló váratlan események bármikor bekövetkezhetnek és a szoftvert
mindezen helyzetek kezelésére fel kell készíteni. Az ilyen esetek tesztelése nehézkes és nem
csak a lehetséges tesztesetek nagy száma miatt, hanem azért is, mert néha speciális
segédeszközökre van szükség az események szimulálásához.

Objektum orientáltság

A felhasználói interfészekhez tartozó ablakok és más grafikai elemek leggyakrabban


objektumok hierarchikus szervezéseként állnak elı, azaz objektum orientált minta alapján
készülnek. Minden objektumnak megvannak a maga metódusai és attribútumai. Az
attribútumok általában jellemzik az objektum állapotát és a következı információkat
hordozzák:
• Az objektum aktív vagy inaktív.
• Megjelenést, mint a betőtípus és méret, helyzet a képernyın, láthatóság.
• Tartalom: szöveg, igaz/hamis, lista elemek száma és nevei.

Az objektumokhoz tartozó attribútumok száma nagy. Egy egyszerő szövegmezıhöz is


legalább harmincféle dolgot lehet beállítani. A tulajdonságok egy része statikus és nem
változik a végrehajtás során. Néhány dologra azonban, amik a felhasználói interaktivitás során
megváltozhatnak, el kell készíteni a megfelelı kezelıeszközöket.

62
Horváth László Szoftvertesztelés a gyakorlatban

Láthatatlan szinkronizácó és függıségek

Ajánlatos az ablakokhoz valamiféle szinkronizációt készíteni. Ha például a felhasználó


bejelöl egy checkboxot, akkor a képernyı másik szélén egy szövegbeviteli mezı aktívvá
válik. Elıfordulhat olyan is, hogy az egyik ablakban végzett változtatás, hatással van egy
másik ablak tartalmára. Ezeknek a függıségeknek és kapcsolatoknak a megállapítása is a
készítık feladata és a tesztelés során erre is figyelni kell. Ez nem egyszerő feladat, hiszen
valamennyire a felhasználó helyébe kell képzelnie magát a programozónak, illetve a rendszer
tervezıinek, hogy rájöjjenek mik lehetnek egy eseménnyel kapcsolatos viselkedésbeli
elvárások.

Végtelen input tartomány

A legtöbb alkalmazásban a felhasználónak lehetısége van bárhova kattintani az aktív


ablakban. Habár az ablakban lévı objektumoknak megvan az elıre meghatározott tabulálási
sorrendje, a felhasználó ettıl eltérhet és az egér segítségével bármelyik beviteli mezıt
kijelölheti, majd kitöltheti. Egy hét elemet tartalmazó ablakban a kitöltési sorrendek száma
7!=5040, és általában ennél jóval több elemet tartalmazó felületekkel kerülünk kapcsolatba.
Vajon egy tesztelınek végig kell gondolnia az összes lehetıséget? És mi a helyzet a
kifelejtett adatokkal? Legyen lehetıség részenként megadni ıket, vagy csak egy teljesen
kitöltött ablakot fogadjunk el? A hiányos adatok kombinációinak száma is szinte végtelen.

Sok út befelé, sok út kifelé

A grafikus felhasználói interfészek sajátosságai miatt a legtöbb szolgáltatás a rendszerben


több helyrıl is elérhetı. Vajon mennyi ezeknek az utaknak a száma? Mindet le kell tesztelni,
vagy csak egy véletlenszerően kiválasztott számút? A kimenı utakkal ugyanez a helyzet. A
felhasználó kattinthat az egérrel egy másik ablakra, használhatja a billentyőzetet is, sıt
valamiféle rendszerhiba is megszakíthatja a munkát. Mekkora tehát a kimeneti utak száma és
kell e tesztelnünk valamennyit?

63
Horváth László Szoftvertesztelés a gyakorlatban

Ablakkezelés

A grafikus interfésszel rendelkezı alkalmazások esetében a felhasználók elvárják, hogy a


szokásos módon kezelhessék azt. Ebbe beletartozik az ablakok átméretezése, áthelyezése,
lecsukása, felnyitása, bezárása. Ezek általában standard parancsokkal végezhetıek és jól
megszokott billentyő kombinációk tartoznak hozzájuk. Néhány dolog az operációs rendszer
szintjén is kezelve van, néhányat azonban az egyedi igényeknek megfelelıen kell kialakítani.
A legtöbb esetben például egy ablak bezárása a módosítások mentése nélkül, bizonytalan
állapotot idéz elı az adatbázis rendszerben. Ezt elkerülendı bizonyos gombokat le kell tiltani
a munka alatt. Hol van a határ az alkalmazás tesztelése és az operációs rendszer tesztelése
között? Le kell tesztelnünk az összes be és kilépési lehetıséget?

5. 3. Tesztelési stratégia

5. 3. 1. Alapelvek

Az itt megfogalmazott alapelveket felhasználva egy olyan tesztelési folyamatot mutatunk


be, amelynek segítségével bármely grafikus interfésszel rendelkezı program tesztelhetıvé
válik. Ne feledjük el, hogy most nem a kód alapján végezzük az elemzést, hanem kizárólag a
GUI-val kapcsolatos hibákat keressük. Sokkal inkább egyfajta fekete doboz tesztelést
végzünk tehát.
• Koncentráljunk a hibákra, hogy csökkentsük a tesztelés körét: Be akarjuk sorolni
a hibákat típusuk alapján néhány csoportba, és a tesztelés során megpróbáljuk a
csoportok tulajdonságai alapján létrehozni a teszteseteket. Így a tesztelés
koncentráltabbá válik és elkerülhetı a kétszeres tesztelés.
• Különítsük el az egyes problémákat (oszt meg és uralkodj): Ha egyszerre csak egy
problémára fókuszálunk, akkor a teljes tesztelésre váró szoftvert sok kis
részproblémaként kezelve a tesztelés egyszerőbbé, jobban átláthatóvá válik.
• Ahol lehet, használjunk tesztelési mintákat: Az eddig tanult fekete doboz tesztelési
formák általában jól alkalmazhatóak a GUI-val kapcsolatos problémák felderítésére is.
• Fokozatos tesztelés: A teszttípusokat állomások sorozataként kell létrehozni. A
tesztelést a komponensek alsóbb szintjén kezdjük és fokozatosan haladunk felfelé. A

64
Horváth László Szoftvertesztelés a gyakorlatban

már tesztelt részeket mindig összeillesztjük, és úgy folytathatjuk a tesztelést, hogy


tudjuk, jól mőködı komponensekbıl építkezünk.
• Automatizálás, ahol lehet: Legtöbbször nagy méretekben nem lehetséges. Ha viszont
elvégeztük a probléma részletekre bontását, akkor a külön egységek már könnyebben
vethetık alá automatikus eszközökkel való tesztelésnek. Amikor csak lehet,
használjuk az automatizálást, lerövidítve a tesztelés idejét!

A grafikus interfész tesztelése során általában három jól elkülöníthetı munkafolyamatot


különítünk el, ami igaz bármely tesztelési eljárásra. Elıször specifikálni kell a tesztet
ugyanúgy, mint egy programozási feladatot. Megfogalmazzuk, mit tesztelünk, hogyan és mik
az elvárások. A következı lépésben elıkészítjük a tesztelést, megírjuk a szükséges scripteket,
segédeljárásokat. A harmadik és egyben befejezı fázis pedig maga a tesztestek futtatása, ami
után feljegyezzük az eredményeket.

5. 3. 2. A hibák típusai

A tesztelés megkönnyítésére végiggondolhatjuk melyek a leggyakoribb hibák egy grafikus


interfésszel rendelkezı alkalmazás esetében. Az itt megadott lista természetesen nem teljes,
de jól mutatja a hibák sokféleségét. A hibák egy része közvetlenül a felülettel kapcsolatos,
másik része pedig a háttérben lévı funkciók, és a felület közötti kommunikációból adódik.
• Adatellenırzés.
• Hibás alapérték beállítások az egyes mezıkhöz.
• Helytelen reagálás a háttérben bekövetkezett hibákra.
• Szükséges és szükségtelen mezık.
• A mőveletek elvégzése után rossz mezıket kapunk vissza.
• A beviteli mezık helytelen sorrendje.
• Az ablak mezıi és az adatbázis mezıi közötti konzisztencia.
• Az ablakok vezérlésére szolgáló funkciók nem, vagy helytelenül mőködnek.
• Szinkronizációs problémák.
• A vezérlés pillanatnyi állapota összhangban van-e az ablakban láthatóval?

65
Horváth László Szoftvertesztelés a gyakorlatban

5. 4. A tesztelés típusai

Ellenırzı listás tesztelés

Az ellenırzı lista alkalmazása egyenes utat biztosít ahhoz, hogy könnyen végezzünk
újrafelhasználható és megismételhetı tesztelést. Sajnos nem túl gyakran alkalmazzák, aminek
oka talán az lehet, hogy túl egyszerő és triviálisnak tőnik. Azonban pont ez az egyszerőség
adja a módszer hatékonyságát. Nagyon jól használható a tesztelés alacsonyabb szintjein a
komponensek tesztelésére és nagyban megkönnyíti a dokumentációt is. Az ellenırzı listák
leggyakrabban használt és legjobban dokumentált elemei:
• Alap programozási/interfész elemek:
o ablak méret, pozíció, modalitás
o standard rendszer parancsok, gombok, mint például minimalizálás, bezárás
• Alkalmazásfüggı szokásos elemek:
o Ok, mégse, folytatás gombok, elrendezés, színek, méretek
o A vezérlı gombok konzisztens használata
o Címkézéshez standard szavak, szövegek használata (segítség, súgó,
kivágás/beszúrás)
Ezek az elemek már a komponensek tesztelése során ellenırizhetık, így akár a programozók
is elvégezhetik, ugyanakkor a teljes alkalmazás tesztelése során is nagy figyelmet érdemelnek.

A navigáció tesztelése

A programozók általában különálló ablakokat tesztelnek munkájuk során. Amikor


azonban egy ablakot, funkciót integrálunk a rendszerbe akkor meg kell vizsgálni, hogy
helyesen illeszkedik-e a többi komponenshez. Meghívható-e a menübıl, vagy más
komponensekbıl, illetve ebbıl az ablakból elérhetı-e mindegyik másik komponens, amire
szükség lehet. Ahhoz, hogy teljes navigációs tesztelést végezzünk a következı dolgoknak kell
rendelkezésre állniuk:
• Az alkalmazás gerince, a legszükségesebb vezérlıelemekkel és hívási
mechanizmusokkal, hogy meghívhassuk az ablakot
• Más ablakok, amelyek meghívják a tesztelésre várót

66
Horváth László Szoftvertesztelés a gyakorlatban

• Olyan ablakok, amelyeket ebbıl az ablakból hívunk

Amennyiben a fenti elemek nem állnak rendelkezésre, akkor gondoskodni kell ezek
szimulálásáról, helyettesítésérıl. Ha ezekkel elkészültünk, akkor a következı dolgokat kell
implementálni:
• Azonosítani kell az összes lehetséges elérési módját az ablaknak, és mindegyikhez
tesztesetet kell készíteni
• Azonosítani kell az összes olyan funkciót, elemet, amelyet az alkalmazás során
elérhetünk az ablakból, és tesztesetet kell készíteni hozzájuk
• Azonosítani kell a megfordítható mőveleteket (például egy meghívott ablak
bezárása után, vissza kell térni a hívó ablakhoz) és teszteseteket kell készíteni
hozzájuk
• Azonosítani kell a vissza nem fordítható mőveleteket (például a hívó ablak
bezáródik a hívott ablak elıtőnésekor) és teszteseteket kell készíteni hozzájuk

Rengeteg módja lehet egy alkalmazáson belül annak, hogy elıhívjunk egy ablakot (menü,
billentyőzet, gombok, stb.). Ilyen esetekben minden egyes lehetıséghez külön tesztesetet kell
készíteni.

Az alkalmazás tesztelése

Ezen a ponton valamilyen fekete doboz tesztelés elvégzése történik, amelynek során
megfigyeljük, hogy a felületen található elemek helyesen mőködnek-e. A hagyományos form
alapú alkalmazások esetében itt kezdıdik a tesztelés. Egyaránt figyelni kell a bemeneti és
kimeneti értékek helyességére, az eredmény megfelelı formában való megjelenítésére.

Kliens-szerver kommunikáció tesztelése

A kliens-szerver kommunikáció tesztelése az elızınek kiegészítése. Ebben a


megközelítésben a desktop alkalmazás integritását vizsgáljuk a szerver folyamatokkal,
amikkel kommunikálni kell. Itt nagy figyelmet kell fordítani a szerver oldalon bekövetkezett

67
Horváth László Szoftvertesztelés a gyakorlatban

hibák kezelésére is. Általában a kliensek közvetlenül a szerverrel kommunikálnak. A


különféle válasz lehetıségeket kell végiggondolni és tesztelni:
• Logolás a szerverre
• Lekérdezések eredményének megjelenítése
• A hibák megfelelı kezelése (szintaxis, szerverleállás)
• Üres lekérdezési eredmények
Természetesen érdekes lehet megvizsgálni a válaszidıt is, ami nagyon jól automatizálható
tesztelési folyamat.

A szinkronizáció tesztelése

A tesztelés során adódhatnak olyan körülmények, amikor a különbözı részek között


összefüggés van. Elıfordulhat például, hogy két ablak van nyitva a képernyın, és valamit
módosítunk az egyikben. Ekkor a másik ablakot esetleg automatikusan újra kell rajzolni, hogy
a bekövetkezett változások ott is megjelenjenek (adatbázisok esetében ez elvárható). Ahhoz,
hogy az ehhez hasonló követelmények teljesüljenek, létre kell hozni valamiféle
szinkronizációt a részek között, amit természetesen le is kell tesztelni. Teszteseteket kell
készíteni a váratlan eseményekhez, illetve a kölcsönös egymásra hatásokra is (két ablak
bármelyikében hajtok végre egy mőveletet, az valamilyen hatással lesz a másik ablak
tartalmára). A tesztelés során arra is figyelni kell, hogy az elvártakon kívül más objektumokat
ne érintsen a változás, hiszen az is hibás mőködést jelent.

Nem funkcionális tesztelés

A fent felsorolt eljárások mind az alkalmazás grafikus felületének funkcionális tesztelését


végzik. Azonban vannak bizonyos nem funkcionális jellemzık és követelmények is, amik ha
nem teljesülnek, ugyanolyan kényelmetlenné tehetik az alkalmazás használatát.
Az egyik ilyen jellemzı a hosszú távon történı egyenletes teljesítés követelménye. Az
alkalmazások tesztelését néha hosszú hónapokig végzik, viszont ez alatt az idı alatt nem
mőködik a rendszer összefüggıen huzamosabb ideig. A hosszú távú mőködés tesztelésére
nagyon gyakran automatikus eszközöket használnak, amik sokszor egymás után hívnak meg

68
Horváth László Szoftvertesztelés a gyakorlatban

bizonyos funkciókat és ellenırzik, hogy azok rendben mőködnek-e és mindig a helyes


eredmény jelenik meg a felhasználó képernyıjén.
Egy másik fontos kérdés a kompatibilitás kérdése. Itt azt kell megvizsgálni, hogy az
alkalmazás a megjelenítés során nem foglal-e le feleslegesen erıforrásokat más alkalmazások
elıl. Ezt általában együtt végzik a hosszú távú teszteléssel oly módon, hogy alkalmazások
egész sorát indítják visszatérı módon és figyelik, hogy milyen hatással vannak egymásra.
A környezeti teszt során azt vizsgáljuk, hogy a különbözı hardver és szoftver
környezetekben hogyan mőködik az alkalmazásunk.

5. 5. A tesztelés automatizálása

Az eddig ismertetett eljárások és alapelvek során nagy hangsúlyt kapott, hogy a tesztelés
megkezdése elıtt alaposan végig kell gondolni, és mindvégig szem elıtt tartani, mik a
céljaink a teszteléssel. Ha ezeket a célokat nem felejtjük el és ezek mentén dolgozunk, akkor a
tesztelés bizonyos fázisai automatizálhatóvá válnak. Az alábbiakban felsorolunk néhány olyan
tanácsot és alapelvet, amelyek hasznosak lehetnek a tesztelés automatizálását elısegítı
eszközök készítéséhez:
• Pareto elv: Az általános bevezetı részben már szó volt a Pareto elvrıl, amely
szerint a hibák 80%-a a kód 20%-ban fordul elı. Ennek egy kissé módosított
változata szerint a tesztelés 20%-nak módosításával 80%-os haszonra tehetünk
szert idıben és erıforrásban.
• Vegyes megközelítés: ahol csak lehet, használjunk segédeszközöket a manuális
tesztelés elıkészítésére, megkönnyítésére, és mindig álljunk készen arra, hogy
bizonyos feladatokat kézzel kell elvégezni, akár a támogató eszközök
meghibásodása miatt is.
• Alkalmi scriptek: A leghatékonyabb akkor alkalmazni ıket, ha olyan kóddal
találjuk szemben magunkat, ami egy általánosan elkészített script segítségével nem
tesztelhetı (például sok ciklus és case utasítás).
• Rögzített scriptek: olyan scriptek, amelyek könnyővé teszik a tesztek
megismétlését.

69
Horváth László Szoftvertesztelés a gyakorlatban

• Tesztek integrálása: a sok különálló scriptet érdemes beintegrálni egy nagyobb


eszközbe. Ajánlatos esetenként saját környezeteket kifejleszteni, mert a
kereskedelmi eszközök túl elnagyolt tesztelést tesznek lehetıvé.
• Nem funkcionális tesztelés: eszközök egész sora alkalmazható a különféle nem
funkcionális jellemzık (válaszidı, memóriafoglalás, stb.) tesztelésére. Bátran
használjuk ezeket, hiszen megfelelı instrumentálás után felgyorsítják a tesztelést.

Ezek után módunk nyílik egy lista összeállítására arról, hogy a felhasználói interfész
tesztelése során melyik folyamatot érdemes automatizálni, illetve melyiket végezzük
manuálisan. Az 5. 1.-es táblázatban láthatóak ezek az ajánlások. Az itt felsoroltak
természetesen nem kötelezı érvényőek, minden szervezetnek megvannak a saját kialakult
szokásai, hogy mit kell kézzel tesztelni, illetve mikor és milyen eszközöket lehet felhasználni
az automatizáláshoz.

Tesztelés típusa Manuálisan vagy automatikusan?


Ellenırzı listás tesztelés Az alkalmazásra vonatkozó szabályokat
manuálisan, míg az objektumok állapotának
a menük mőködésének vizsgálatára
automatikus eszközök is használhatóak.
Navigáció tesztelése Automatizált tesztelés
Alkalmazás tesztelése (BVA, ekvivalencia A bonyolult, vagy kismérető teszteket
osztályozás, stb.) manuálisan végezzük, míg a sok egyforma
részt tartalmazó hosszadalmas tesztelés
automatizálható.
Kliens-szerver kommunikáció Egyszerő tranzakciók tesztelése
automatizálva, az összetettebb folyamatoké
pedig kézzel.
Szinkronizáció Manuális tesztelés.
Nem funkcionális tesztelés Automatikus tesztelés.

5. 1. táblázat. Manuális vagy automatikus tesztelés?

70
Horváth László Szoftvertesztelés a gyakorlatban

5. 6. A felhasználói felület tervezése a könnyebb tesztelhetıség érdekében

Az alábbiakban a felület tervezık számára fogalmazunk meg néhány dolgot, annak


érdekében, hogy az általuk készített interfész könnyen tesztelhetı legyen. Amennyiben
lehetıség van rá, érdemes ezeket a dolgokat is bevenni az ellenırzı lista segítségével végzett
tesztelés pontjai közé. Az ajánlások némelyike kétségtelenül egyfajta kényszert ró a
felhasználóra, de ha megfelelı alapossággal és körültekintéssel végeztük az alkalmazás
tervezését és implementálását, akkor minimális számú szokatlan dologgal fog a felhasználó
találkozni.
1. Ahol az alkalmazásban többféle módon is végrehajtható egy-egy mővelet, érdemes
a felesleges, redundanciát okozó menüpontokat szürkévé tenni, vagy más módon
kikapcsolni.
2. Amennyiben a specifikációban nincs külön rögzítve, hogy ugyanazokat az
adatokat több ablakban is megjelenítsük, próbáljuk minél jobban függetleníteni az
ablakok tartalmát, elkerülve így az inkonzisztencia lehetıségét.
3. Az ablakok közötti navigáció legyen hierarchikus, elkerülve így azt, hogy
egyidejőleg túl sok ablak legyen nyitva.
4. Egészen addig, amíg az nem megy a használhatóság rovására, érdemes az
ablakokban megjelenı adatokat függetleníteni egymástól oly módon, hogy a
felhasználó külön ablakokban végezheti a mőveleteket.
5. Az ablakon szereplı rendszermőveletek (maximalizálás, minimalizálás, bezárás,
stb.) számát próbáljuk meg minimálisra redukálni.
6. Ha egy mővelet több gomb, vagy menüpont segítségével elvégezhetı, a háttérben
használjuk ugyanazokat a funkciókat és eljárásokat a hibalehetıségek
minimalizálása és a tesztelés megkönnyítése érdekében.
7. Instrumentáljuk fel megfelelı módon az alkalmazást annak érdekében, hogy a
tesztelıknek lehetıségük legyen a rendszerfolyamatok ellenırzésére, nem várt
események hatásainak vizsgálatára, illetve szándékos elıidézésére.

71
Horváth László Szoftvertesztelés a gyakorlatban

Láthattuk, hogy a grafikus felhasználói interfész megjelenése bonyolultabbá,


komplexebbé tette az alkalmazásokat, növelte a hibalehetıségek számát, és megnehezítette a
tesztelık dolgát. A következetes teszttervezés segítségével lehetıségünk nyílik, a fontos
tesztekre való koncentrálásra. Könnyebben ki tudjuk szőrni a nagy kockázattal járó részeket
az alaposabb tesztelés érdekében. Eszközöket készíthetünk és használhatunk a tesztelés egyes
folyamatainak automatizálására, illetve az automatizálható részek azonosítására.

72
Horváth László Szoftvertesztelés a gyakorlatban

6. Objektumorientált tesztelés

A tesztelés három alapvetı folyamata a tervezés, az elıkészítés és a tesztek futtatása


természetesen nem változik objektumorientált rendszerek tesztelése során sem. Ezek a
rendszerek azonban rendelkeznek néhány sajátossággal, amiket nem hagyhatunk figyelmen
kívül a tesztelés során sem:
• Adatelrejtés
• Független objektumok saját állapotokkal, amelyek egymásra hatnak (nincs egy
megosztott globális állapot)
• A rendszer viselkedésének vizsgálatán van a hangsúly a struktúra helyett
• Kód újrafelhasználás
• Öröklıdés
• Egységbezárás

A fent felsorolt tulajdonságok nem jelentkeznek egy funkcionális programnyelv esetén.


Az adatelrejtés lehetısége miatt a tesztelıknek inkább fekete doboz tesztek futtatására van
lehetıségük, azaz csak az objektumok interfészén keresztül vizsgálhatják a pillanatnyi
állapotukat. Az öröklés lehetısége miatt elıfordulhat, hogy bizonyos dolgokat többször is
tesztelni kell, ami természetesen többlet erıforrás felhasználást igényel. Megjegyezzük, hogy
itt csupán nagyvonalakban tekintjük át a lehetséges megközelítéseket és az elıforduló
problémák körét, de a széleskörő kutatásoknak köszönhetıen az érdeklıdık nagy számban
találhatnak a témához kapcsolódó irodalmat.

6. 1. Teszttervezés

Négy lehetséges szintje van az objektumorientált rendszerek tesztelésének. Az elsı az


objektumokhoz kapcsolódó egyedi mőveletek szintje. Ezen mőveletek tesztelése elvégezhetı
a korábban ismertetett funkcionális és strukturális technikák segítségével. A második szint az
objektumosztályok tesztelése. Itt már mőveletsorozatok tesztelésére kerül sor, valamint
megvizsgáljuk az objektumok viselkedését a hozzájuk tartozó metódusok és adattagok
segítségével. A harmadik szint, amikor az objektumok egy csoportját kell tesztelni. A
hagyományos fentrıl lefelé, illetve lentrıl felfelé történı integráció nem alkalmas az

73
Horváth László Szoftvertesztelés a gyakorlatban

összefüggı objektum csoportok tesztelésére. Valamilyen újfajta megközelítésre van szükség.


Végül a teljes objektum orientált rendszer tesztelése, ahol a rendszerkövetelmény specifikáció
verifikációja és validációja megegyezik a más rendszereknél alkalmazottakkal, és amelyek
ismertetésétıl ebben a dolgozatban eltekintünk. Mi most a második és a harmadik szinttel
fogunk foglalkozni.

6. 1. 1. Objektumosztály tesztelése

Az objektumorientált rendszereknél várható hibák esetében végig kell gondolni, a


rendszer jellegzetességébıl adódóan néhány dolgot. Bizonyos hibák nyilvánvalóan kisebb
valószínőséggel fognak elıfordulni, míg másfajta hibákkal többször találkozhatunk.
Elıkerülhetnek (és valószínőleg elı is kerülnek), olyan újfajta hibák, amelyekkel még nem
találkoztunk. Ezek az öröklıdés és a többalakúság miatt jöhetnek létre. Amikor meghívunk
egy függvényt, nem lehet teljes pontossággal megmondani, hogy melyik osztályhoz tartozó
kódot fog meghívni. Problémát okozhat a paraméterek típusának meghatározása is. Ha a
kódolás megengedi, érvénytelen típusokkal meghívva egy eljárást nem várt hibák léphetnek
fel. Az alapvetı különbség az eddigiekhez képest egy példán keresztül érthetı meg a
legjobban. Eddig, ha megláttuk az „x = fv(y)” utasítást, egy egyszerő függvény viselkedését
vizsgáltuk. Objektum orientált esetben viszont végig kell gondolni, hogy ez az fv() függvény
most az alaposztály::fv(), vagy pedig a származtatott osztály::fv() függvény. Egy függvény,
illetve eljárás hívásakor meg kell vizsgálni minden lehetıséget a viselkedéssel kapcsolatban.
Ez természetesen egy jó tervezési mintát követve egyszerőbbé válik, hiszen a gyakorlatban
igyekeznek minél kisebb különbséget tenni az alap és a származtatott viselkedés között. Az
objektum orientált nyelvekben a függvények általában rövidebbek, így sokkal inkább
integrálási problémák lépnek fel nem pedig mőködésbeliek. A nem objektum orientált
programnyelven készült szoftverek esetében sokszor elhanyagoljuk az integrálásra vonatkozó
tesztelést.
Az objektumorientált rendszerek legfontosabb elemei maguk az objektumok és a hozzájuk
tartozó változók. A tesztelés során meg kell vizsgálni a változók viselkedését is, amit a
pillanatnyi értékük határoz meg. El kell végezni az objektumhoz tartozó összes mővelet
különálló tesztelését a korábban megismert technikák segítségével, valamint szimulálni kell
az összes olyan eseményt, amely állapotváltozást okoz az objektumban. Általában a
metódusok különállóan tesztelhetıek, viszont elıfordulhat, hogy bizonyos esetekben

74
Horváth László Szoftvertesztelés a gyakorlatban

tesztsorozatra van szükség. Tegyük fel, hogy adott egy osztály, amely egy hımérséklet mérı
állomás irányításáért felelıs. Minden órában be kell kapcsolni egy mőszert, ami megméri a
pillanatnyi hımérsékletet. Ebben az esetben a bekapcsolás önállóan tesztelhetı, viszont a
kikapcsolás teszteléséhez elıször be kell kapcsolni a mőszert. Érdemes tehát a kettıt együtt
vizsgálni. Az objektumok állapotainak teszteléséhez egy állapotmodell használatára van
szükség. Ennek a modellnek a segítségével azonosítható a tesztelendı állapotátmenetek
sorozata és meghatározhatók az állapotátmenetek eléréséhez szükséges események. Általában
az összes állapotátmenet sorozatot tesztelni kell, a gyakorlatban azonban, a magas költségek
miatt, sokszor csak részleges tesztelést végeznek.
Mivel objektumorientált rendszerekben gyakran alkalmazzák az öröklést, mint nyelvi
eszközt, így el kell gondolkozni az alosztályok objektumainak és mőveleteinek tesztelésén is.
Olyan esetekben, amikor egy alosztály örököl egy mőveletet a szuperosztálytól, minden
örökölt mőveletet tesztelni kell, hiszen ezek a mőveletek felhasználhatnak más mőveleteket és
attribútumokat, amik viszont megváltozhattak a származtatás során. A felülírt mőveletekkel
hasonló a helyzet. A könnyebb tesztelhetıség érdekében annyi engedmény tehetı, hogy egy
eljárásnak vagy függvénynek csak azon részeire kell új teszteseteket készíteni, ahol
változásokat idézett elı a származtatás és esetleg új hibák kerülhettek a rendszerbe. Tegyük
fel például, hogy adott két osztály, amelyek többek között a következı függvényeket
tartalmazzák:
• Alap osztály:
o inherited(int x)
o redefined() – 1 és 10 közötti számokkal tér vissza
• Származtatott osztály:
o redefined() – 0 és 20 közötti számokkal tér vissza

Tegyük fel továbbá, hogy az inherited() függvény a következı kódot tartalmazza:


If(x<0){
x = x/redefined();
return x;
}
Ebben az esetben elég azokra az esetekre újratesztelni az inherited() függvényt ahol a
bemeneti érték kisebb, mint 0. A többi esetre biztosak lehetünk, hogy továbbra is helyesen fog
mőködni, mert ott nem hívjuk meg az újradefiniált függvényt.

75
Horváth László Szoftvertesztelés a gyakorlatban

Felmerülhet a kérdés, hogy vajon alkalmazhatóak-e az alaposztályhoz megírt tesztesetek a


származtatott osztály metódusaira, attribútumaira is? Mindkét osztálynak megvan a maga
specifikációja, és ez alapján mindkettıhöz megterveztük a szükséges teszteseteket. Nagy
valószínőséggel átfedés lesz a két teszt specifikációjában. A gyakorlatban a származtatott
osztály tesztelésekor felhasználhatjuk az alaposztályhoz készített tesztesetek közül azokat,
amelyek mindkettıben szerepelnek. Bizonyos tesztesetek teljes egészében átvehetıek, míg
néhány esetben a tesztértékek ugyanazok de más lesz az elvárt eredmény, így itt csak
részleges átvétel történik.
Természetesen az objektumorientált rendszerek esetében is gyakran elıfordulnak
elgépelésbıl származó hibák, amik a korábban ismertetett eljárásokkal kiszőrhetıek.

6. 1. 2. Objektumintegráció

Eddig az osztályokat és objektumokat, mint különálló egységeket vizsgáltuk. Nem szabad


azonban figyelmen kívül hagyni, hogy egy rendszer objektumok interakciójaként áll elı. Az
objektum orientált rendszerek esetében sem a fentrıl lefelé, sem pedig a lentrıl felfelé való
integrálásnak nincs igazán értelme, hiszen nehéz meghatározni mi a fent, azaz mi az integrálás
célja. Csoportokat kell képezni az objektumosztályokból és ezeket kell együtt tesztelni.
Az elsı lehetséges megközelítés a használati eset alapú tesztelés. A rendszer
specifikációjában megfogalmazhatunk úgynevezett használati eseteket. Ezekben rögzítik,
hogy a rendszer használói milyen interakcióba léphetnek a rendszerrel, és ezek hatására
milyen folyamatokat kell végrehajtani. A tesztek ezek leírásain alapulhatnak. Azokat az
objektumokat kell tehát együtt vizsgálni, amelyek egy használati esetben szerepelnek,
együttmőködnek.
A második tipikus megközelítési forma a száltesztelés. Ez a fajta tesztelés a rendszernek
bizonyos bemenetekre vagy eseményekre adott válaszán alapszik. Az objektumorientált
rendszerek gyakran eseményvezéreltek, amely sajátosságot kihasználjuk a tesztelés során.
Ahhoz, hogy ezt a technikát használhassuk, meg kell határoznunk, hogy a feldolgozás során a
rendszernek mely részei lépnek mőködésbe és merre halad a vezérlés az objektumok között.
A használati eseteken alapuló megközelítés gyakran a leghatékonyabb, ugyanis a
használati esetek alapján megállapítható, hogy melyek a rendszer leggyakrabban használt
részei és ezek tesztelését elıre vehetjük. A tesztelés során természetesen elıfordulhat, hogy ki
kell egészíteni a használati eset diagrammokat a tesztelés célkitőzéseinek pontosítása

76
Horváth László Szoftvertesztelés a gyakorlatban

érdekében. Egy teljes forgatókönyv tesztelés során ráadásul figyelembe kell venni a
kivételeket, és azok helyességét is meg kell vizsgálni.
A tesztek tervezése során érdemes ellenırzı listákat készíteni, amelyek segítségével
nyilvántarthatjuk, hogy melyik metódusokat teszteltük már. Természetesen lehetetlen az
összes lehetséges kombinációt lefuttatni, de így legalább biztosítjuk, hogy minden metódus
tesztelve lett valamely sorozat részeként.

77
Horváth László Szoftvertesztelés a gyakorlatban

7. Tesztelı eszközök

Manapság az egyre kiterjedtebb kutatásoknak és fejlesztéseknek köszönhetıen számos


ingyenes és kereskedelmi szoftvert találhatunk, amelyek változatos módon szolgálják a
tesztelés folyamatát. A tesztelı alkalmazások valamilyen formában biztosítják a
tesztkörnyezetet egy adott hardver és szoftverkörnyezetben. Általában elmondható, hogy a
napjainkban divatos programozási nyelvek mindegyikéhez találhatunk ilyen eszközöket.
Ebben a fejezetben felsoroltam néhányat ezek közül pár mondatos leírással, és az
elérhetıségükkel együtt.

AdaTEST95

Ada95 programozás nyelvhez készült tesztkörnyezet, amely lehetıséget nyújt a fejlesztık


számára, hogy hatékonyan végezzenek unit és integrációs teszteket az elkészített
alkalmazásokon. Nagyszerő lehetıségeket nyújt a lefedettség vizsgálatához, és statikus
vizsgálatok elvégzéséhez.
A termék fı jellemzıi:
• Unit és integrációs tesztelés
• Integrált lefedettség elemzı, metrikák támogatása
• Ada95 és Ada83 támogatás
• Objektum orientált tesztelés
• Interfészek szimulálásának lehetısége (stubolás)
• Statikus elemzés a komplexitásról és a méretekrıl
• Dinamikus tesztelési lehetıségek, fehér és fekete doboz tesztelés támogatása
• Unix és Windows környezetre is elérhetı
A termékkel kapcsolatos további információk, és megrendelés a
http://www.ipl.com/products/tools/pt600.uk.php weboldalon.

78
Horváth László Szoftvertesztelés a gyakorlatban

C++ Test

Komplett eszközkészlet kódelemzéshez, automatikus unit és komponensteszteléshez,


lefedettség elemzéshez és regressziós tesztek végzéséhez. Lehetıségünk van grafikus
használatra és parancssori futtatásra egyaránt. Szolgáltatásait tekintve körülbelül megegyezik
az AdaTEST95-el nagymértékő támogatással a csapatmunka végzéséhez. Ez is kereskedelmi
szoftver, amellyel kapcsolatos bıvebb információk a http://www.parasoft.com oldalon.

CppUnit

Ingyenes tesztelı eszköz C++ nyelven készült programok teszteléséhez, amely


gyakorlatilag a JUnit megfelelıje. Lehetıséget nyújt automatikus és irányított tesztelés
végzésére. A tesztelés eredménye elmenthetı XML és egyszerő szöveges formában is. Elıre
beépített test scriptek szolgálják a kényelmesebb és gyorsabb munkavégzést, továbbá
lehetıségünk van az általunk készített tesztesetek és scriptek elmentésére, amiket a
késıbbiekben felhasználhatunk. További információ és letöltés a
http://cppunit.sourceforge.net/cppunit-wiki weboldalon.

HttpUnit

Egy Java könyvtár web alkalmazások tesztelésére. Lehetıségünk van böngészı program
használata nélkül hozzáférni weboldalakhoz a szükséges tesztelések elvégzéséhez. A HttpUnit
a http protokoll szimulálása révén támogatja különbözı formokkal kapcsolatos feladatok
elvégzését, lehetıség van JavaScript futtatására és alapvetı autentikációs mőveletek
elvégzésére. Lehetıségünk van a visszakapott oldalakat egyszerő szövegként, valamint
formok, táblázatok és linkek halmazaként kezelni. Bármely Java futtató platformra elérhetı a
http://httpunit.sourceforge.net oldalon. Hasonló tulajdonságokkal rendelkezik a HtmlUnit
nevő eszköz is: http://htmlunit.sourceforge.net.

79
Horváth László Szoftvertesztelés a gyakorlatban

JUnit

Széles körben használt és nagyon kedvelt Java nyelven íródott programok teszteléséhez.
Nagy mértékben támogatja regressziós tesztek végzését beépített függvények segítségével.
Néhány Java fejlesztıkörnyezetbe eleve integrálják az eszköz használatának lehetıségét,
elismerve ezzel képességeit (pl. NetBeans). Függvényhívások szimulálásával végezhetı a
tesztelés, melynek során elıre beállíthatjuk mi az elvárt eredmény. Lehetıség van grafikus
formában megtekinteni az eredményt és a tesztelést is indíthatjuk egy grafikus interfészen
keresztül. Természetesen kódból is hívható és beépíthetjük programjainkba. Az ingyenesen
letölthetı Java kiegészítés és a hozzátartozó dokumentáció elérhetı a http://www.junit.org
weboldalon.

PhpUnit

Hasonlóan C++ -os társához a PhpUnit is a JUnit alapján készült és hasonló


szolgáltatásokat nyújt. Az eszköz használatához szükségünk van egy cvs szerverre, ahol
dolgozni tudunk a tesztelés során. A tesztek parancssorból indíthatók és az eredmény
táblázatos formában tekinthetı meg. A PhpUnit használatához hasznos információkat és
példakódokat találunk a http://sourceforge.net/projects/phpunitcookbook oldalról letölthetı
dokumentumban.

Rational Test RealTime (RTRT)

A Rational cég által kifejlesztett tesztkörnyezet, amelynek segítségével lehetıségünk van


Java, C/C++, Ada83 és Ada95 nyelven készült programok unit tesztelését elvégezni. A
teszteléshez scripteket kell készítenünk, amelyekben megadjuk, hogy mit tesztelünk, milyen
értékkel és mit várunk el eredményként. A szoftver automatikusan ellenırzi a kód
lefedettségét, és ajánlásokat tesz, milyen további tesztesetekre van szükség a teljes és kimerítı
teszteléshez. Sokoldalú program, amelynek elsajátítását nagyban segíti a grafikus felület és a
rengeteg beépített segítség. A termék kereskedelmi forgalomban kapható, megrendelhetı a
következı oldalon: http://www-306.ibm.com/software/awdtools/test/realtime. Itt
lehetıségünk van egy 15 napos próbaverzió letöltésére, amiben kipróbálhatjuk a teljes
szolgáltatási palettát, majd egy license kulcs megrendelésével véglegesíthetjük a terméket.

80
Horváth László Szoftvertesztelés a gyakorlatban

8. Összefoglalás

A dolgozat elkészítésével szerettem volna egy összefoglaló képet adni a rendelkezésre álló
és a gyakorlatban jól használható tesztelési módszerekrıl, eljárásokról. Igyekeztem mindenhol
a témának megfelelı, azt jól szemléltetı példákat találni, megkönnyítve ezzel a megértést.
Ahogy azt az elsı fejezetben megjegyeztem kutatásaimat fıleg a unit tesztek szintjén
végeztem, hiszen a programozók leggyakrabban ezen a szinten dolgoznak és végzik saját
munkájuk tesztelését. A cél az volt, hogy egy tömör képet adjak a tesztelésnek errıl a
szintjérıl, rávilágítva a problémákra és a lehetséges megoldásokra. A dolgozat végén
ismertetett segédeszközök közül volt alkalmam néhányat a gyakorlatban is kipróbálni. Az
olyan termékek, mint az RTRT igazán remek lehetıséget nyújtanak azoknak, akiknek egy
komplett tesztrendszerre van szükségük és sikeresen alkalmazhatók nagyobb vállalati
projektek tesztelésére is. Ha viszont csak kisebb alkalmazásokat szeretnénk tesztelni, akkor
készíthetünk a JUnithoz hasonló osztályokat, szinte bármelyik manapság elterjedt
programnyelvhez. A dolgozatban leírtak alapján könnyebb lehet az elindulás ilyen eszközök
készítéséhez.
A másik fontos dolog, amit a diplomamunkámmal kapcsolatban meg kell említeni az,
hogy a készítése során rendkívül kevés magyarnyelvő anyagot találtam. Sajnos hazánkban
nem nagyon van olyan könyv, amely mérvadónak számítana szakmai körökben éppen ezért
nehéz az információk megszerzése. A dolgozat jó alapot szolgáltat az egyetem hallgatóinak is
a tesztelés alapjainak elsajátításához.

81
Horváth László Szoftvertesztelés a gyakorlatban

Irodalomjegyzék

[1] Jan Sommerville: Szoftverrendszerek fejlesztése, Panem Kiadó, 2001,


ISBN: 978 963 545 3
[2] R. Binder: Testing Object-Oriented systems, Addison-Wesley, 2000,
ISBN: 0201809389
[3] M. Hutcheson, Software Testing Fundamentals, Wiley, 2003,
ISBN: 047143020X
[4] P. Jorgensen, Software Testing, CRC Press, 2002,
ISBN: 084930809-7
[5] Dr. Kovács Attila: A szoftverfejlesztés minıségi aspektusai elıadás, elektronikus
jegyzet: http://compalg.inf.elte.hu/~attila
[6] Wikipedia, ingyenes enciklopedia, http://en.wikipedia.org/wiki/Decision_table
[7] Dr. Hassan Reza: Black Box Testing, elektronikus jegyzet:
http://people.aero.und.edu/~reza/Csci565-Bk-testing.ppt
[8] Gregory M. Kapfhammer, Software Testing, CRC Press, 2004, elektronikusan:
http://cs.allegheny.edu/~gkapfham/research/publish/software_testing_chapter.pdf
[9] Paul Gerrard, Testing GUI Applications, Edinburgh, 1997, elektronikusan:
http://www.gerrardconsulting.com/GUI/TestGui.html
[10] Heckenast Tamás, Szoftver minıségbiztosítás, elektronikus jegyzetek,
http://rs1.szif.hu/~heckenas/okt
[11] Jiantao Pan, Software Testing, Carnegie Mellon University, 1999, elektronikusan:
http://www.ece.cmu.edu/~koopman/des_s99/sw_testing
[12] Forgács István, Szoftvertesztelés, elektronikus jegyzet:
http://www.ilab.sztaki.hu/~ahajnal/jegyzet
[13] Peter Sestoft, Systematic software test, Royal Veterinary and Agricultural University,
1998, elektronikusan: http://www.itu.dk/people/sestoft/programmering/struktur.pdf

82

You might also like