OO rendszerek jellemzői Problémák forrása lehet teszteléskor: Problémák feldarabolása. Adatrejtés. Az OO rendszerek nagyszámú, egymással aktívan kapcsolatban levő, együttműködő komponensekből állnak. A OO programozás másik jellemzője, a komponensek jól definiált interfészen történő elérése, és ezzel párhuzamosan a nem publikus adatok és funkciók elrejtése. 1
OO rendszerek jellemzői A problémák további forrásai lehetnek nyelvi sajátságok: C++-ban használatos virtuális függvények Az ilyen kódba rejtett, implicit elágazások kezelése igen nehéz tesztelés során. A OO paradigmában széleskörűen használt polimorfizmus egyazon kód használati környezettől függő értelmezésése 2
Lefedettségi analízis OO kód esetén strukturális mértékszámok közvetlen használata igen megtévesztő lehet. Környezettől függő lefedettség Kidoloztak az OO rendszerek tesztelésének alaposságának jellmzésére alkalmas egyedi mértékszámokat, valamint a strukturális teszteléskor használt mértékszámok OO rendszerekben használható változatát. 3
Tesztelés nem OO rendszerekben A nem OO rendszerek tesztelésekor használt tipikus tesztkörnyezetek, módszerek bemenetek biztosítása a tesztelt szoftver (SUT) számára, SUT működtetése, kimenetek, esetleges belső változók megfigyelése. A leggyakrabban használt tesztelési módszer az elsősorban modulteszteléskor használt izolációs tesztelés. 4
Az izolációs tesztelés előnye A szoftver komponensei egyenként is tesztelhetőek, adott esetben még a többi rész elkészülte előtt. Tesztelhető először a komponensek belső működése, majd ezt követően az interfészek. A tesztkörnyezet egy adott szoftver egymást követő verzióiban újrahasználható. A tesztelés megfelelő teszt környezet esetén jól automatizálható. 5
Hagyományos tesztelés OO környezetben Izolációs tesztelés Az izolációs tesztelés alkalmazásakor a legnagyobb gondot a környezet kialakítésa jelenti. Problémát jelent a teszt környezet (csonkok) újrafelhasználása is. Az izolációs technikát ezért általában nem gyakran használják OO rendszerek tesztelésekor. Ezzel szemben a bottom-up tesztelést, mely sok vonatkozásban hasonló az izolációs technikához, annál többször. 6
Hagyományos tesztelés OO környezetben Bottom-up tesztelés A tesztelő részekre osztja a SUT-t Egyes önállóan tesztelt részeket azonban rétegeknek nevezzük A csak már tesztelt osztályra épülő osztályok tesztelése addig tart, míg az egész szoftvert le nem teszteltük A problémát a körkörös hivatkozások jelentik Ekkor vagy egyszerre teszteljük az összes, körben szereplő osztályt, vagy az izolációs technikát használjuk, vagyis a hivatkozott osztályok egy részét a teszt környezet segítségével (csonkok formájában) implementáljuk. 7
OO rendszerek tesztelési technikái Tesztelhetőségre tervezés Wrapper osztályok használata Tesztelés állapot-átmenet diagramm alapján 8
Tesztelhetőségre tervezés A tesztelhetőség olyan általános szempontokként fogalmazható meg mint: Kerülni kell a nem feltétlenül szükséges kapcsolatokat osztályok között. Lehetőséget kell adni az adatok (belső változók) megfigyelésére, beállítására. Kerülni kell a virtuális függvények felesleges használatát. A fenti kitételek sajnos nagyon általánosak, az OO programozás eszköztárát lényegesen korlátozzák. 9
Absztrakt Bázis Osztályok Ennek a tesztelhetőre tervezési technikának a lényege, hogy az osztályok interfészét egy külön osztályban valósítják meg absztrakt (függvénytörzs nélküli virtuális) függvényekként. Ekkor ugyan a rendszerben levő osztályok száma megnő, azonban könnyebben lehet az egyes osztályokat egymástól elhatárolni, és alkalmazni az izolációs technikát. 10
Wrapper osztályok használata Az OO rendszerekben nehézséget okoz az objektumokban használt rejtett adatok megfigyelése és beállítása A nyelvek többsége (pl.: C++, Java) lehetőséget ad azonban egyes osztályok közötti speciális viszony (friend) deklarálására, ami lényege, hogy a két osztály kódjából elérhetővé válik a másik osztály belső változói és függvényei. 11
Wrapper osztályok használata A tesztelő környezetben minden osztályhoz létrehozhatunk egy wrapper osztályt, mely a deklarációk megfelelő megadásával elérheti a tesztelt osztály belső változóit. A wrapper osztályt a tesztelt osztállyal azonos interfésszel hozzuk létre. A wrapper osztály adott függvény meghívásakor dokumentálja a meghívás tényét, a hívási paramétereket, majd meghívja a tesztelt osztály eredeti függvényét. 12
Wrapper osztályok használata Class A public függvény hívás Wrapper Class B public Class B public return private private Teszt dokumentáció 13
Tesztelés állapot-átmenet diagramm alapján Az objektumok működése jól modellezhető egy állapot automatával. A tesztelt szoftver rendszer reprezentációja a hozzá tartozó objektumokat leíró automaták halmaza lesz. Az egyes objektumokhoz tartozó automaták kapcsolatát, a teljes rendszer működését egy rendszer szintű állapot automatával írhatjuk le. Az egész rendszer így eseményvezérelten működik, a bemenetek hatása végig szalad az egész rendszeren. 14
Tesztelés állapot-átmenet diagramm alapján külsô esemény szál válasz receptor emitter tesztelt rendszer határa komponens osztályok állapot modelljei 15
Mértékszámok használata Elsősorban OO szoftverteszteléshez definiált mértékszámok: Belépési pont lefedettség - Entry point coverage. Kölcsönös hívás lefedettség - Call-pair coverage. Környezetfüggő mértékszámok: Öröklésfüggő lefedettség - Inheritance context coverage Állapotfüggő lefedettség - State based context coverage Szálfüggő lefedettség - Thread based context coverage 16
Belépési pont fedettség Azt mutatja meg, hogy egy adott objektum publikus interfészében definiált függvények mekkora hányadát hívtuk meg a tesztelés folyamán. A mértékszám előnye, hogy alkalmas az esetlegesen nem megvalósított, így nem meghívható függvények felderítésére. 17
Kölcsönös hívás lefedettség Arányszám, ami megadja, hogy két objektum között lehetséges függvényhívások mekkora hányada került ténylegesen meghívásra a teszt végrehajtása során. Ugyanazon függvény különböző kódrészletekből történő hívásait megkülönbözteti. 18
Környezet függő mértékszámok A polimorfizmus miatt egy adott kódrészlet a program különböző helyeiről, különböző (program) környezetből hívható. A meghívott kód működése függhet a meghívási (aktivizálási) környezettől, így az alapos teszteléshez hozzátartozik az adott kódrészlet minden lehetséges környezetből történő meghívása, tesztelése. 19
Öröklésfüggő döntés lefedettség A különböző elágazások bejárását objektum környezetenként megkülönböztjük. Melyik leszármazottból történt a hívás? 20
Állapotfüggő lefedettség Olyan környezet függő mértékszám csoport, ahol a hívási környezet figyelembevételekor nem csak a hívó objektum típusát, hanem annak aktuális állapotát is figyelembe vesszük. Ezeket a mértékszámokat az állapotátmenet diagramm alapján történő tesztelés során használják. 21
Szálfüggő lefedettség Többszálú alkalmazások tesztelése esetén lehet hasznos, amikor a mértékszám számításakor a hívó szál azonosítóját is figyelembe vesszük. A szálak azonos közös kódot hajtanak végre, tesztelési szempontból fontos, hogy egy adott kódrészlet melyik szál környezetében került végrehajtásra. 22
Konkrét tesztelő rendszerek Cantata++ SGI Tester Aprobe 23
Cantata++ IPL Ltd. Bath C++ szoftverek egység és integrációs tesztjeihez A teszt a tesztelendő forráskód, a teszt script és a "Cantata++ Test Harness" fordításával ill. linkelésével keletkező futtatható program. A teszt scriptek C++ nyelven íródnak és tulajdonképpen egy main függvényből állnak, ami végrehajtja a tesztelendő szoftveregységet. 24
Cantata++ "SM Tool A forráskód beműszerezése, mely C++ friend deklarációk és wrapping formájában jelentkezik. A csonkok (stub) írása a felhasználóra marad, de megadható, hogy teszteléskor az egyes meghívásokkor milyen visszatérési értékei legyenek a szimulált függvénynek. 25
Cantata++ A teszt scriptekben ellenőrizhetők az adatelemek értékei ill. ellenőrizhetők azok az adatterületek melyek értékeinek nem szabad változniuk a teszt futása alatt. A Cantata lehetővé teszi hogy mérjünk különböző végrehajtási időket. A beműszerezés ellátja a kódot teszt lefedettségi metrikák meghatározásához szükséges adatgyűjtő részekkel. 26
SZOFTVER-MINŐSÉGBIZTOSÍTÁS Cantata++ 27
SGI Tester Silicon Graphic Inc. ProDev debugger-csomag dinamikus teszt lefedettség analízis eszköze A végrehajtható kód speciális beműszerezésére szolgál, teszt lefedettségi adatok gyűjtésére és lehetővé teszi ezen adatok grafikus felületen való elemzését. C, C++ és Fortran programokhoz használható A rendszer script nyelve lehetővé teszi olyan parancssor orientált programok automatizált tesztelését, melyek viselkedését indításukkor megszabhatjuk. 28
SZOFTVER-MINŐSÉGBIZTOSÍTÁS SGI Tester 29
Aprobe (RootCause) OC Systems Inc. Java, C Nem intruzív tesztelő, debuggoló és teljesítmény-optimalizáló rendszer. műszerezési eljárás abban különbözik a szokásos tesztelő környezetekétől, hogy a tesztelendő programot a forráskód újrafordítása és linkelése nélkül teszi alkalmassá a tesztelésre A próbák az eredeti végrehajtható kóddal mint patchek egy "dynamic action linking" nevű eljárással kerülnek kapcsolatba. 30
SZOFTVER-MINŐSÉGBIZTOSÍTÁS Aprobe (RootCause) 31