11.3. Kliens oldal tesztelése

A kliens oldal tesztelése két részből áll: kliens oldali logika tesztelése, ami a modell állapotának ellenőrzése, és a kliens oldali kérések hatásának ellenőrzése (kérés megy a szerver oldalhoz, ahonnan visszajön a válasz, amit a kliens eltárol a logikában). Mi ingyenes megoldásokat kerestünk, ami sajnos Flex téren elég szegényes. Egységtesztre számos megoldás létezik, azonban felülettesztre, integrációs tesztre nincs jelen pillanatban. Lehetőség van Selenium, Watir és más tesztek futtatására, de ezen teszt esetek tervezése, implementálása jelentős réfordítás igényel. A FLex rendszerben bevezették az ExternalInteface-t, ami segítségével Flex alól lehet javascript elemeket használni és vissza felé is adott a kommunikáció. Azonban minden esetben nekünk kell megírnunk a metódusokat, amiket engedélyezünk a külvilág felé. Vannak üzelti megoldásokon alapuló ingyenes megoldások mint például a FlexMonkey, ami olyan csomagot használ az Adobe-tól, amit meg kell vennünk. Ennek segítségével könnyen felépíthetjük és elvégezhetjük az integrációs és felület tesztjeinket. Kliens oldalon elég az egység teszt. Itt is számos megoldás kínálkozik, FlexUnit ( nyilt forrású), amit a Flesh develop beépített modulja is támogat, Fluint, ami egység és integrációs teszteket is képes kezelni. Mi a Fluint rendszert vállasztottuk, mert segítségével lehet metódusokat aszinkron módon hívni, támogatja a grafikus elemek (UIComponent) tesztelését, teszt szekvenciákat is definiálhatunk (integrációs teszt), XML kimenetet is támogatja (automatizálható, Hudson-ba integrálható), használható Ant rendszerrel.

11.3.1. Egységteszt

A kliens oldali Egység/funkcionális tesztelésre több lehetőség is adódik: FlexUnit, Fluint.

Fluint telepítése egyszerű, egy programozói könyvtárat kell csak letöltenünk: fluint-1.1.1.swc, amit meg kell adnunk a fordítónak is. Ezt Flash Develop esetén egyszerű másolás, majd a jobb gomb a fájlon és "Add To Library" paranccsal tehetjük meg. Ezután a források, mxml fájlok készítése során használhatjuk a könytárban levő osztályokat. Hasonlóan a JUnit-hoz itt is osztályokat kell írnunk, majd azokat futtatni. Lehetőség van grafikusan (AIR Flash) vagy karakteres felületen futtatni (így lehetőség van. Az egységtesztet úgy építjük fel, hogy a teszt metódusok végén ellenőrizzűk valmilnyen álltítás helyességét. A teszt metódusaink a teszt esetekben helyezkednek el, ami egy sima osztály a TestCase leszármazottja. A teszt függvényeinkhez metainformációkat is fűzhetünk a függvény fejlece előtt. Lehetőség van több információt is megadni, leírást, hiba vagy kérés ID-t, bármit ami szükséges.

11.7. példa - Metainformációk megadásának módja a Fluit teszt eset függvényhez

[Test(description="Test is supposed to Fail",issueID="0012443")]
public function fails2():void {}


A Fluit rendszer semilyen módon nem korlátozza a lehetséges paraméterek nevét és értékét. Amit megadunk azt ki fogja írni az összesítésnél. Itt is használhatjuk a megszokott setUp() és tearDown() metódusokat. Álltalában a setUp()-ban hozzuk létre az időzítő objektumot (Timer), amit a tearDown()-ban leállítunk és a referanciáját null-ra állítjuk (ezután a szemétgyűjtő felszabadít). A teszt készlet (TestSuit) osztály fogja össze atest eseteintket, ami egy általunk definiált osztály (TestSuit leszármazottja). A rendszer maga definiál egy FrameworkSuite-t, ami tartalmaz teszt eseteket (TestCase osztályokat) amelyek támogatják különböző típusú tesztelést is: aszinkron tesztelés, felhasználói felület tesztelést, stb. . A fejelsztés alatt szükség van valamilyen grafikus teszt futtató alkalmazás létrehozására, és annak használatára. Szerencsére a Fluit tartalmaz egy AIR alkalmazást, amely lefuttatja a tezteket majd mutatja a az eredményeket. Ehhez a letölthető SampleTestRunner mxml fájlt kell felülírnunk. Ennek a kódja a következő:

11.8. példa - A Fluit grafikus teszt futtató alkalmazásának kódja

<?xml version="1.0" encoding="utf-8"?>
<mx:Application 
xmlns:mx="http://www.adobe.com/2006/mxml" 
xmlns:fluint="http://www.digitalprimates.net/2008/fluint"
layout="absolute"
creationComplete="startTestProcess(event)"
width="100%" height="100%">

<mx:Script>
<![CDATA[
import net.digitalprimates.fluint.unitTests.frameworkSuite.FrameworkSuite;

import testSuitSample.SampleTestSuit;

protected function startTestProcess( event:Event ) : void
{
var suiteArray:Array = new Array();
1suiteArray.push( 2new SampleTestSuit() );

testRunner.startTests( suiteArray );
}

]]>
</mx:Script>

<fluint:TestResultDisplay width="100%" height="100%" />
<fluint:TestRunner id="testRunner"/>
</mx:Application>

1

Újabb teszt készlet elindítása.

2

A Teszt készlet objaktuma.


Az (1) es sort annyiszor kell megismételni a megfelelő (2)-es objektummal ahány teszt készletünk van. Miután elkészítettük a megfelelő teszt futtatú grafikus mxml fájlt, fordítsuk le az alkalmazásunkat úgy, hogy ez a fájl adja az alkalmazásunk fő ablakát (Flash develop alatt ez az Always Compile). futtatsuk a projektet, ezután a teszt futtató ablakát fogjuk látni, amely a háttérben lefuttatja a teszteket, majd megjeleníti az eredményeket.

Grafikus elemeke tesztelése a Fluint rendszerrel lehetséges, de számos dologra oda kell figyelni. Ez valójában már integrációs teszt, ami a rendszerünk együttműködését teszteli. Ismernünk kell a Fluit lehetőségeit, kéynszereit, mert ennek tudatában kell az eredeti rendszer is elkészíteni. A vezérlők nem jelennek meg rögtön a felhelyezés után, és az állotuk sem lesz azonnal helyes, hanem több inicializáló műveletet végeznek. Ez különböző számítógépen különböző ideig tarthat. A tesztnek mindenképpen meg kell várni ezt az előre nem megjósolható időt. Erre a rendszer megoldást kínál. Mindaddíg várnunk kell, amíg egy vezérlő inicializálódott és helyesen megjelent. Az aszinkron setUp() és az tearDown() függvényekkel ezt a porblémát megoldhatjuk. Hozzunk létrre agy teszt esetet majd végezzük el a következő lépéseket:

11.9. példa - Grafikus elem tesztelése Fluint segítségével

        override protected function setUp():void {
                1textInput = new TextInput();
                2textInput.addEventListener(FlexEvent.CREATION_COMPLETE, 3asyncHandler( 4pendUntilComplete, 1000 ), false, 0, true );
                5addChild( textInput );
        }

1

Hozzuk létre a megfelelő grafikus vezérlőt!

2

Adjunk hozzá egy saját esemény figyelőt, amely a a lértehozás végén fut majd le!

3

Használjuk az aszinkron figyelő típust!

4

Használjuk a Fluit-ban definiált függvényt, ami nem csinál semmit!

5

Adjuk hozzá az adott vezérlőt a teszt környezethez (TestEnvironment)


Az (5)-ös lépésnél az addChild függvénnyel hozzáadjuk a grafikus elemet a teszt esethez, ami furcsának tűnhet. A teszt eset nem egy grafikus elem (UIComponent), de rendelkezésre áll a façade tervezési minta a helyes működés érdekében. A vezérlők a memóriban léteznek inicializálódnak, de amíg nem adjuk valamilyen tárolóhoz (Container), nem lesznek valamely elem gyermekei, nem fut le az elrendező (layout) függvény, addig nem működnek helyesen. A tesz futtató implementálja ezt a speciális egyke mintát,a minek a neve testEnvironment, amely a következő függvényeket implementálja a tesztelés érdekében:

  • addChild

  • addChildAt

  • removeChild

  • removeChildAt

  • removeAllChildren

  • getChildAt

  • getChildByName

  • getChildIndex

  • setChildIndex

  • numChildren

A teszt eset lefutása után meg kell szüntetni a mellékhatásokat, azaz a létrehozott vezérlőt le kell szedni a felületről és ki kell jelölni törlésre, melyet a következő kóddal érhetünk el:

11.10. példa - A mellékhatást megszüntetető tearDown metódus a Fluit rendszerben

 override protected function tearDown():void {
                1removeChild( textInput );
                2textInput = null;
        }

1

Szedjük ki a felület gyereklistájából!

2

Állítsuk a referenciát null-ra, így majd törli a szemétgyűjtő a következő alkalommal!


A vezérlők beállítása és annak ellenőrzése a következő kóddal lehetséges:

11.11. példa - Vezérlő tartalmának beállítása és ellenőrzése

 public function testSetTextProperty() : void {
                1var passThroughData:Object = new Object();
                2passThroughData.propertyName = 'text';
                passThroughData.propertyValue = 'digitalprimates';
                
                3textInput.addEventListener( FlexEvent.VALUE_COMMIT, asyncHandler( handleVerifyProperty, 100, passThroughData, handleEventNeverOccurred ), false, 0, true );
                4textInput.text = passThroughData.propertyValue; 
        }

5protected function handleVerifyProperty( event:Event, passThroughData:Object ):void {
                6assertEquals( event.target[ passThroughData.propertyName ], passThroughData.propertyValue );
        }

7protected function handleEventNeverOccurred( passThroughData:Object ):void {
                8fail('Pending Event Never Occurred');
        }

1

Hozzunk létre egy egyszerű objektumot, ami tárolja a beállítandó értéket a megfelelő formában!

2

A propertyName propertyValue értékeiket állítsuk be a kívánt értékre!

3

Adjunk egy FlexEvent.VALUE_COMMIT esemény figyelőt, amelyben figyeljük majd a sikeres vagy sikertelenség tényét.

4

Rendeljük a vezérlő értékéhez a kívánt értéket!

5

Definiáljunk egy metódust a sikeres értékadás esetére!

6

Ellenőrizzük a kívánt hatást a assertEquals metódus segítségével!

7

Definiáljuk a handleEventNeverOccurred metódust arra az esetre, ha a beállítás nem futott le sikeresen!

8

A tesztelő keretrendszernek küldjük el a sikertelenség tényét a fail metódus használatával!


A futás eredményét grafikusan elemezhetjük, és a piros régióra klikkelve kinyílik a hibás, vagy helytelen eredményt adó függvény, melyet a következő ábrán láthatunk:

11.9. ábra - Egységteszt eredményének ablaka

Egységteszt eredményének ablaka