Verifikáció és validáció
Minőségbiztosítás
A szoftver verifikációja és validációja, vagy minőségbisztosítása azon folyamatok összessége, amelyek során ellenőrizzük, hogy a szoftver teljesíti-e az elvárt követelményeket, és megfelel a felhasználói elvárásolnak.
- A verifikáció ellenőrzi, hogy a szoftvert a megadott funkcionális és nem funkcionális követelményeknek megfelelően valósították meg. Történhet formális, vagy szintaktikus módszerekkel.
- A validáció ellenőrzi, hogy a sziftver megfelel-e a felhasználók elvárásainak, azaz jól specifikáltuk-e eredetileg a követelményeket. Alapvető módszere a tesztelés.
Verifikáció és modifikáció módszerei
- Statikusan, a modellek és a programkód áttekintésével
- elvégezhető a teljes program elkészülte nélkül is
- elkerüli, hogy hibák elfedjék egymást
- tágabb körben is felfedhet hibákat, pl. szabványoknak történő megfelelés.
- Dinamikusan, a program futtatásával.
- felfedheti a statikus ellenőrzés során észre nem vett hibákat, illetve a programegységek együttműködéséből származó hibákat.
- lehetőséget ad a teljesítmény mérésére
Tesztelés
A tesztelés célja a szoftverhibák felfedezése és szoftverrel szemben támasztott minőségi elvárások ellenőrzése.
- futási idejű hibákat, működési rendellenességeket keresünk, kompatibilitást ellenőrzünk.
- általában a program futtatásával, szimulált adatok alapján történik.
- nem garantálja, hogy a program hibamentes, és minden körülmény között helytáll, de felfedheti a hibákat adott körülmények között.
A teszteléshez tesztelési tervet készítünk, amely ismerteti a tesztelés felelőseit, folyamatát, technikáit és céljait.
Tesztesetek
A tesztelés során különböző teszteseteket különböztethetünk meg, amelyek az egyes funkcióját, illetve elvárásokat tudják ellenőrizni.
- megadjuk a bemenő adatokra várt eredményt
- a teszteseteket összekapcsolhatjuk a követelményekkel (traceability matrix)
- a teszteseteket gyűjteményekbe helyezzük (test suit) A tesztesetek eredményeiből készül a tesztjelentés (test report)
Tesztelés lépései
A tesztelés nem a teljes program elkészülte után, egyben történik, hanem általában 3 szakaszból áll:
- fejlesztői teszt: a fejlesztők ellenőrzik a program működését
- jellemzően white box tesztek, azaz a fejlesztő ismeri, és követi a programkódot.
- kiadásteszt: egy külön tesztcsapat ellenőrzi a szoftver használatát
- felhasználói teszt: a felhasználók tesztelik a programot a felhasználási környezetben
- jellemzően black box, azaz a forráskód nem ismert.
A fejlesztői tesztnek további három szakasza van:
- unit test: a programegységeket külön-külön, egymástól függetlenül teszteljük.
- integrációs teszt: a programegységek együttműködésének tesztje, a rendszer egy komponensének vizsgálata
- rendszerteszt: az egész rendszer együttes tesztje, a rendszert alkotó komponensek közötti kommunikáció vizsgálata
Unit tests
Az egységteszt során törekednünk kell arra, hogy a programegység összes funkcióját ellenőrizzük, egy osztály esetén
- ellenőrizzük valamennyi metódust
- állítsuk be, és ellenőrizzük az összes mezőt
- az összes lehetséges állapotba helyezzük az egységet
A teszteseteket célszerű leszorítani a programegység által
- megengedett bemenetekre, így ellenőrizve a várt viselkedést
- nem megengedett bemenetre, így ellenőrizve a hibakezelést
A bemenő adatokat részhalmazokra bonthatjuk a különböző hibalehetőségek függvényében, és minden részhalmazból egy bemenetet ellenőrizhetünk.
Az egységtesztet az ismétlések és a számos kombináció miatt célszerű automatizálni.
Előnyök
- A hibák sokkal korábban észlelhetőek
- Minden komponens legalább egyszer tesztelt
- Az egységek elkülönítése miatt a hibák helyének meghatározása könnyű
- A funkciók könnyen módosíthatóak, átalakíthatók
- Dokumentációs szerep: példákat biztosít egyes funkciók használatára
Elvek
- Gyors: A teszteknek gyorsan kell futnia, lassú teszteket senki nem futtatja gyakran, így a hibák nem derülnek ki idejében.
- Független: A teszteknek egymástól függetlennek és bármilyen sorrendben végrehajthatónak kell lennie.
- Megismételhető: A teszteknek bármilyen környezetben, hálózat nélkül is végrehajthatónak kell lennie. A különböző futtatások eredményének meg kell egyeznie.
- Önellenőrző: A tesztek eredménye egy logikai érték (futásuk vagy sikeres, vagy sikertelen)
- Automatikus: Automatikusan, interakció nélkül futó tesztek
Mock
- A tesztelt metódusok általában más komponens nyújtotta szolgáltatásokat is használnak
- Az egyes funkciókat más komponensektől izoláltan kell tesztelnünk, a tesztek sikeressége nem függhet a függőségek helyes implementációjától
- A Mock egy olyan objektum, amely egy másik objektum működését szimulálja
- Egy osztály függőségeinek szimulálására használandó
Tesztelési keretrendszerek
Az egységtesztek automatizálását, és az eredmények kiértékelését hatékonyabbá tehetjük tesztelési keretrendszerek használatával.
- általában a tényleges főprogramoktól függetlenül építhetünk teszteseteket, amelyeket futtathatunk, és megkapjuk a futás pontos eredményét
- a tesztesetekben egy, vagy több ellenőrzés kap helyet, amelyek jelezhetnek hibákat
- amennyiben egy hibajelzést sem kaptunk egy tesztesettől, akkor az eset sikeres, egyébként sikertelen
Kódlefedettség
A tesztgyűjtemények által letesztelt programkód mértékét nevezzük kód lefedettségnek.
- megadja, hogy a tényleges programkód mely részei kerülnek végrehajtásra a teszt során
- számos szempont szerint mérhető:
- mely alprogramok lettek végrehajtva
- mely utasítások lettek végrehajtva
- az elágazások mely ágai futottak leű
- a logikai kifelyezések mely részei lettek kiértékelve
További tesztek
Az integrációs és rendszertesztek során elsősorban azt vizsgáljuk, hogy a rendszer megfelel-e a követelménybeli elvárásoknak.
- funkcionális és nem funkcionális alapon (pl. teljesítmény, biztonság) is ellenőrizhetjük a rendszert
- ezeket a teszteseteket már a specifikáció során megadhatjuk
- a tesztelés első lépése a füst teszt (smoke test), amely során a legalapvetőbb funkciók működését ellenőrzik
A kiadásteszt és a felhasználói teszt során a szoftvernek már általában a célkörnyezetben, tényleges adatokkal kell dolgoznia
Teljesítménytesztek
A teljesítménytesztek (performance test) során a rendszer teljesítményét mérjük
- ezáltal a rendszer megbízhatóságát és teljesítőképességének (válaszidők, átviteli sebességek, erőforrások felhasználása) ellenőrizzük különböző mértékű feladatvégzés esetén
- végezhetünk teszteket a várható feladatmennyiség függvényében (load test), vagy azon túl ellenőrizhetjük a rendszer tűrőképességét (stress test)
- a teljesítmény tesztet sokszor a hardver erőforrások függvényében végezzük, amellyel megállapítható a rendszer skálázhatósága (capacity test)
Debugging
A tesztelést elősegíti a nyomkövetés (debugging), amely során a programot futás közben elemezzük, követjük a változók állapotait, a hívás helyét, felfedjük a lehetséges hibaforrásokat
- breakpoint elhelyezése
- watch, amely automatikus lokális változókra
- call stack kezelése, a felsőbb szintek változóinak nyilvántartása
Programváltozatok
Az implementáció és tesztelés során a szoftver különböző változatait tartjuk nyilván:
- pre-alpha: funkcionálisan nem teljes, de rendszertesztre alkalmas
- alpha: funkcionálisan teljes, de minőségi mutatókat nem teljesíti
- beta: funkcionálisan teljes, és a minőségi mutatók javarészt megfelelnek a követelményeknek
- a további tesztelés során nagyrészt a rendellenességek kiküszöbölése folyik, a tesztelés lehet publikus
- esetlegesen kiegészítő funkciók kerülhetnek implementálásra
- release candidate: funkcionálisan teljes, minőséfi mutatóknak megfelelő
- kódteljes
- csak dinamikus tesztelés folyik, és csak kritikus hiba esetén nem kerül gyártásra
- final release: kiadott, legyártott változat
Tesztvezérelt fejlesztés
A tesztvezérelt fejlesztés egy olyan fejlesztési módszertan, amely a teszteknek ad elsőbbséget a fejlesztés során
A fejlesztés lépései:
- tesztesetek elkészítése, amely ellenőrzi az elkészítendő kód működését
- az implementáció megvalósítása, amely eleget tesz a teszteset ellenőrzéseinek
- az implementáció finomítása a minőségi elvárásoknak (tervezési és fejlesztési elvek) megfelelően
Előnye, hogy magas fokú a kód lefedettsége, mivel a teszteknek minden funkcióra ki kell térniük.