A mutációtesztelés ( mutációanalízis vagy programmutáció ) egy szoftvertesztelési módszer , amely a programkód kis változtatásait foglalja magában. [1] Ha egy tesztcsomag nem észlel ilyen változásokat, akkor az elégtelennek minősül. Ezeket a változtatásokat mutációknak nevezzük , és mutáló utasításokon alapulnak, amelyek vagy utánozzák a gyakori programozói hibákat (például rossz operátor vagy változónév használata), vagy hasznos tesztek létrehozását követelik meg.
A mutációtesztet Richard Lipton diák javasolta 1971-ben [2] , és először DeMille, Lipton és Seyward fejlesztette ki és publikálta. A mutációt vizsgáló eszköz első megvalósítását Timothy Budd, a Yale Egyetem munkatársa alkotta meg disszertációjában ("Mutational Analysis") 1980-ban.
A mutációtesztelési módszer számításigényes, és a közelmúltig nem volt népszerű. Az utóbbi időben azonban ez a módszer ismét felkeltette az informatika területén kutatók érdeklődését.
A mutációteszt a mutáló operátorok kiválasztásából és egyenkénti alkalmazásából áll a program forráskódjának minden egyes darabjára. A mutáló operátor egy forráskód-átalakítási szabály. Egy mutációs operátor programra történő egyszeri alkalmazásának eredményét mutánsnak nevezzük . Ha a tesztkészlet képes észlelni a változást (azaz az egyik teszt sikertelen), akkor a mutáns elpusztult . Vegyük például a következő részletet egy C++ programból:
if ( a && b ) { c = 1 ; } másik { c = 0_ _ }A feltétel mutáció operátor helyére , és a következő mutáns jön &&létre ||:
if ( a || b ) { c = 1 ; } másik { c = 0_ _ }Ahhoz, hogy a teszt elpusztítsa ezt a mutánst, a következő feltételeknek kell teljesülniük:
Ezeket a feltételeket együttesen RIP-modellnek nevezzük .
A gyenge mutációteszthez (vagy gyenge mutációs lefedettséghez ) csak az első két feltételnek kell teljesülnie. Az erős mutációteszthez mindhárom feltétel teljesülése szükséges, és biztosítja, hogy a tesztkészlet valóban észlelni tudja a változást. A gyenge mutációk tesztelése szorosan összefügg a kódlefedési technikákkal . A teszt ellenőrzése egy gyenge mutáció körülményei között sokkal kevesebb számítást igényel, mint egy erős mutáció feltételeinek ellenőrzése.
Sok mutációs utasítás egyenértékű programokhoz vezethet. Vegyük például a következő programrészletet:
int index = 0 ; míg ( ... ) { … ; index ++ ; if ( index == 10 ) { szünet ; } }A feltétel mutáció operátor helyettesíthető ==a >=következő mutánssal:
int index = 0 ; míg ( ... ) { … ; index ++ ; if ( index >= 10 ) { szünet ; } }Nincs azonban olyan teszt, amely megölné ezt a mutánst. A kapott program megegyezik az eredeti programmal. Az ilyen mutánsokat ekvivalens mutánsoknak nevezzük .
Az ekvivalens mutánsok felismerése az egyik legnagyobb akadály a mutációs tesztelés gyakorlati alkalmazásában. A mutáns egyenértékűségének ellenőrzésére irányuló erőfeszítés még kis programok esetében is nagyon nagy lehet. [3]
Sokféle mutációs operátort feltártak már. Például kötelező nyelvekhez a következő operátorok használhatók:
Ezen kívül vannak operátorok az objektum-orientált nyelvekhez, [4] operátorok a párhuzamos programozáshoz, [5] operátorok adatstruktúrákhoz , például konténerekhez [6] stb.