Automata funkcionális GUI tesztelési minták

Bevezető

Az automata funkcionális tesztelési megoldás létrehozása nem sokban különbözik a programfejlesztéstől. Az automatatesztelés újdonság, amely sok javításon, fejlődésen, szabványosításon ment keresztül. Új eszközök jönnek/jöttek létre, hogy könnyebben kommunikálhassunk a tesztelés alatt álló rendszerrel. (System Under Test - SUT)

A metodológiák és megközelítések széles választéka áll a rendelkezésünkre jelenleg: objektum-orientált programozás, funkcionális programozás, DDD, TDD, BDD, stb. Ezek a megközelítések konkrét, meghatározott koncepcióval és tételekkel rendelkeznek, amelyek egyszerűen definiált folyamatokból állnak a rendszer architektúrájára, megértésére, vagy a fejlesztőkkel való kommunikációra tekintve.

Legtöbbször én is a GUI tesztautomatizálását támogató eszközöket keresem, amikor a tesztelés alatt lévő rendszerre (SUT) fekete dobozként tekintek. (Az SUT arra a rendszerre utal, amelyiken a folyamattesztelésre kerül. Asztali alkalmazás esetén maga az alkalmazás, böngésző esetén a weboldal, vagy a webes projekt.) Ez leginkább a régi vállalati rendszerekre, vagy az olyan új fejlesztésekre igez ahol a tesztelhetőségi, minőségi jegyeket nem tartották szem előtt.

Az előkészület és a legfontosabb feladatok definiálása kritikus lépés az automata tesztelés megvalósításához. A következő ábra egy tradicionális kapcsolatot mutat a tesztelés alatt álló rendszer (SUT) és a tesztelő szakember között:

1. ábra: Kapcsolat a tesztelő és a SUT között

A rendszer központjában az ember, maga a tesztelő áll. A tesztelő a tesztesetekben leírt szkenáriókat ismételgeti manuálisan és vizuálisan ellenőrzi a rendszert, vagy speciális eszközökkel, melyek az SUT nem látható interfészeihez kapcsolódnak. A nem várt viselkedéseket, vagy hibákat a hibakövető rendszerben tartja nyilván.

A legfőbb jelentősége az automatatesztelésnek az SUT humán interakcióinak kizárásában (minimalizálásában) van. Ez egy nagyon gyakori követelmény a termékfejlesztési ciklusban. Az átnézett irodalmi források azt mutatják, hogy rengeteg automatizálást segítő rendszer létezik. Az üzleti alkalmazások legtöbbször speciális követelményeket és elvárásokat definiálnak a működésre vonatkozóan, de nehéz definiálni mik azok a szoftver elemek, amelyek alkalmasak az automatatesztelésre.

Természetesen az automata teszteszköz gyártók gyakran folyamodnak marketing trükkökhöz és megpróbálják az eszköz előnyeit az aktuális alkalmazás néhány funkcionális tesztesetének ismeretében felvázolni. Ahogy az automata tesztek számossága növekszik, úgy válik a tesztek karbantartása is a folyamat legköltségesebb részévé.

Az automatatesztelési keretrendszerek arra vannak, hogy ezeket a problémákat kiküszöböljék az újra felhasználható komponensekkel, „best practice”-ekkel és egységes automatizálási megközelítésekkel.

Automata funkcionális tesztelési minták

Példaként nézzük meg egy webalkalmazás automatizálásának problémáját (2. ábra). Az alkalmazás tartalmaz egy bejelentkező képernyőt. Minden automata tesztnek keresztül kell mennie a bejelentkezésen, hogy a további funkcionalitáshoz hozzáférjen.

2. ábra: Egy egyszerű web alkalmazás, néhány weblappal és minimális funkcionalitással.

Az osztályozó séma (3. ábra) egy általánosított nézet az összes funkcionális teszt-mintára, amit később fogok kifejteni.

3. ábra: Automata tesztminták osztályozása

Kivitelezési minták

Rögzített

A teszt végrehajtást az automata teszteszköz végzi olyan módon, hogy rögzíti a tesztelő cselekvéseit, majd visszajátssza azokat. Néhány esetben nem ez a célravezető, mert nagyon megdrágíthatja a karbantartás költségeit.

Programozott

A tesztelést egy fejlesztő az automata eszköz API-jának (alkalmazásprogramozási interfész) segítségével végzi (pl.: Selenium WebDriver API)

Sablon használata (Teszt sablon)

Egy alap sablon osztály implementálása. A teszteset variációk a teszt sablon örököltetéséből és az osztály funkcionalitásának bővítéséből alakíthatóak ki.

Adatvezérelt kivitelezés

Egy alapvető tesztet egy teszteset határoz meg. A teszt variációk különböző bemeneti adatok kombinációjaként valósul meg.

Ez a szemlélet majdnem az összes unit teszt keretrendszerben megtalálható. Például az MSTest hozzáférést biztosít a DataContext tulajdonsághoz a teszten belül. Ugyanez a teszteset többször, de különböző (a DataContext-ben eltárolt) bemeneti adatokkal képes futni.

Kulcsszó vezérelt megvalósítás

A tesztek implementációja kulcsszavak (általában az angol kifejezések) segítségével történik (Click, Enter, stb.). A tesztek speciális IDE-k (integrált fejlesztői környezet) segítségével valósulnak meg, amelyek segítenek hozzáférni az alkalmazás felhasználói felületéhez. Számos teszteszköz képes a kulcsszó-vezérelt implementációkra. A tesztlépések a kulcsszavakból, a felhasználói felület objektumainak nevéből és a bemeneti paraméterekből állnak. Jó példa az efféle IDE-kre a HP QTP, vagy a MonkeyTalk.

Modell vezérelt megvalósítás

Egy alkalmazás egy bizonyos időpillanatban, meghatározott bemeneti paraméterekkel csak egy adott állapotban létezhet. A definíció alapján az alkalmazás úgy képzelhető el, mint egy véges állapotú gép (véges automata). Figyelembe véve ezt a tényt, valamint az alkalmazás állapotait és az átmeneteket (2. ábra) definiálhatunk bizonyos átmeneti eseteket (munkafolyamatokat) a weblapok között, amelyek lefedik a legtöbb funkcionalitást.  

Architekturális minták

Többrétegű teszt megoldások

Különböző logikai szintekre osztja a tesztrendszert.

Széles körben bevett gyakorlat a rendszert architekturálisan rétegekre osztani. Az első szint a megjelenítés logikája, a második szint az üzleti logika, a harmadik pedig az adattárolás szintje. Ennek a paradigmának a használata csökkenti a karbantartási költségeket, mert bármelyik szinten változtatunk a komponensekben annak minimális hatása lesz a többi szint elemeire. Ugyanez a megközelítés alkalmazható a tesztrendszerben is.

A teszt kódokat fel lehet osztani három szintre: az automatizált eszköz interfészeinek szintjére, a funkcionális logika szintjére és a tesztesetek szintjére. Minden szintnek különböző felelőssége van a közös cél elérése érdekében, hogy csökkentsük a tesztelés és a karbantartás költségeit, valamint elősegítsük az új tesztek létrehozását.

4. ábra: A tesztrendszer többrétegű architektúrája

Meta keretrendszer

A minta egy sor független segédosztályokat definiál, amely minden automata eszköz számára általános és újra felhasználható a különböző automata projektekben.

Az ilyen megoldások a különböző projektek belső tesztelésében elengedhetetlenek, ahol vállalati sztenderdekhez és egységesítésekhez kell alkalmazkodni. A Meta keretrendszerek a kódok projektek közötti újrafelhasználásában segítenek, mivel jól használható metódusokat tartalmaznak. Az alap osztályok - mind funkcionális, mind teszt objektumok tekintetében – segítik a projektek közötti tudástranszfert. A 4. ábra jobb oldalán látható a Meta keretrendszer.

Funkcionális minták

Funkcionális eljárás

A minta az alkalmazásra vonatkozó üzleti funkciók absztrakciója (elvonatkoztatása) a felhasználói felület, az API, vagy egyéb szinteken.

A legtöbb automata eszköz képes az úgynevezett „rögzített esetekre”, amikor is a tesztet létrehozó szakember az adott alkalmazáson különböző műveleteket végez, és ezekből automatikusan teszt szkriptek készülnek. Ezek a rögzített esetek később visszajátszhatóak és ellenőrizhetőek, hogy a kód változtatása esetén is hiba nélkül működnek-e a funkciók.

Példa: a bejelentkező képernyő megjelenítésének a megváltoztatása minden feltételezett kimenetre befolyással van. Ha a bejelentkezés az Application.Login(Felhasználónév/jelszó) eljárással valósul meg és minden esetben ezt használjuk a tesztekhez, csak egy helyen kell megváltoztatni a folyamatot ahhoz, hogy minden tesztben megváltoztatásra kerüljön.



5. ábra: Interakció a teszt szkript és a felhasználói felület között a funkcionális eljárás átmeneti rétege nélkül(a) és a réteggel (b). A kitöltött objektum változik, amikor az alkalmazás változik.

Oldal objektum

A funkcionális eljárások csoportja egy bizonyos weboldalon.
A funkcionális eljárások az alkalmazásban (2. ábra) a számosságuk miatt akár egyetlen osztályba is helyezhetőek, de a kód karbantartásának az optimalizálásához célszerű csoportokba rendezni, amit csak lehet. Például:

  • PageLogin: Login()
  • PageHome: Logout(), CreateUser().

Funkcionális könyvtár

Ez a funkcionális objektumokat és eljárásokat fűzi egy csoporttá az újrafelhasználhatóság érdekében.

A SUT elindulási és befejezési objektumai (SUT Runner)

Lehetővé teszi a tesztelendő rendszer elindítását és inicializálását, miután az objektumok felvették a kezdeti értékeiket.
A funkcionális eljárások között különbséget tehetünk aszerint, hogy melyek azok, amik nem relevánsak a funkcionális tesztelésben. Például:

  • A böngésző indítása és a bejelentkező képernyőre való navigálás a SUT-ban.
  • A teszt lefutása után a böngészőnek be kell csukódnia.
A „SUT futtató” felelős az ilyen műveletekért.
Objektumforrás (Object Mother)

Objektumokat hoz létre és a megfelelő formára inicializálja a tesztek futtatásához.

Szállító (Navigator)

Egységbe foglalja a navigálást a tesztelendő rendszerben a tesztelési követelményekhez igazodva.

Ez az objektum magába foglalja a navigáció egész logikáját a tesztrendszerben, így az üzleti logikában lévő hibák nem lesznek hatással a navigációra.

Az 2. ábra segít a megértésben. Van egy szállító osztály a következő eljárásokkal:
NavigateToLogin(), NavigateToHomePage(), NavigateToCreateuser() stb. Alternatív megoldás lehet, ha minden oldal objektum rendelkezik a saját szállító metódusával.

Összetett oldal objektum

Összeköti az újrafelhasználható oldal objektumokat egyetlen belső osztállyá.

Ez a minta az oldal objektumok strukturálásában segít egy sokkal objektum-orientáltabb módon, hogy a gyerek objektumok újrafelhasználhatóak legyenek a különböző oldalakon és beilleszthetőek legyenek a szülő objektumokba.



Ábra 6: A Navigációs oldal objektum használata a Home és Create User oldal objektumokban.

Kiterjesztett Oldal objektum

Kiterjeszti az alap oldal objektumokat, hogy származtatni lehessen belőlük akár egy összetett oldal objektumot.

Folyamat minták

Given/When/Then

Felosztja a tesztfuttatást három különböző állapotra:

  • given (az előfeltételek definiálása);
  • when (speciális feladatok, amelyek az alkalmazáson futnak);
  • then (az eredmények ellenőrzése).

Négy állapot teszt

Négy állapotra osztja fel a tesztfuttatást:

  • Előfeltételek definiálása
  • Üzleti funkciók meghívása
  • Eredmények ellenőrzése
  • Rendszer leállítás
Folyamat Teszt

Egy tesztben üzleti folyamatokat és ellenőrzéseket futtathatunk, melyk a végső cél elérése érdekében váltogathatóak.

Összetett hibák

Ez a minta abban segít, hogy a nem kritikus hibák ismeretében a tesztek még tovább futtathatóak legyenek.

Teszt függőségi minta

Önálló teszt

Futása után a tesztelt rendszert a tesztelés előtti állapotában adja vissza.

Láncolt teszt

Előkészítő teszt, amelyik a tesztelésre készíti fel a SUT-t.

Tesztcsoportosítási minta

Teszt metódusok teszt objektumonként

A teszt metódusokat minden osztály külön-külön definiálja.

Csoportosított teszt metódusok a teszt osztályokban

A csoportosított teszt metódusok külön teszt osztályokban vannak.

Következtetés

A tesztelési folyamat megtervezésének a motorja a megfelelő kivitelezési minta kiválasztása. Ez adja a kiindulási pontot a jövőbeli tesztelési megoldások fejlesztéséhez, meghatározza a megértést, az olvashatóságot, a karbantarthatóságot és számos más tulajdonságot. Továbbá ha egyszer bevezetünk egy ilyen mintát, akkor az nagy valószínűséggel később, másik projekten is újrafelhasználható lesz, így időt és költséget takaríthatunk meg a következő automata tesztelésünkben.
Ez a bejegyzés csak gondolatokat tartalmaz, hogy hogyan építsünk ki tesztelési megoldásokat a különböző minták használatával.

Felhasznált irodalom:

  1. “Design Patterns: Elements of Reusable Object-Oriented Software” by Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides ©1994, Addison-Wesley Professional;
  2. “xUnit Test Patterns : Refactoring Test Code” by Gerard Meszaros ©2007 Addison-Wesley;
  3. Design Patterns for Customer Testing by Misha Rybalov, Quality Centered Developer;
  4. Meta-Framework: A New Pattern for Test Automation by Ryan Gerard and Amit Mathur, Symantec, Security 2.0;
  5. Selenium - Wiki page

Forrás: http://www.infoq.com/articles/gui-automation-patterns

Szerző:
Oleksandr Reminnyi

<< Vissza