Archiv pro měsíc: Červen 2010

Automatické testování Java aplikace pomocí nástrojů TestNG a Apache ANT (Unit testing)

Tento článek popisuje způsob automatického testování JAVA aplikací pomocí nástrojů TestNG a Apache ANT. Testovaná aplikace je napsána na platformě J2EE pomocí frameworku JBoss Seam.

Před časem jsem dostal za úkol vyřešit automatické spouštění unit testů pro aplikaci, kterou vyvíjíme. Jako vývojové prostředí používáme Eclipse. Samotné unit testy píšeme pomocí nástroje TestNG. Cílem tedy bylo vytvořit nástroj, který si stáhne aktuální verzi aplikace z SVN repository. Aplikaci zkompije a spustí testy. Tedy se jedná o tzv. unit testy.

Úkol jsem si nejprve rozdělil na několik dílčích částí:

  • stažení dat z SVN serveru
  • build aplikace
  • spuštění unit testů

Stažení dat z SVN, jak se později ukázalo, je velice snadné. Použil jsem Apache ANT a knihovny pro práci s SVN:

<path id="svnant.class.path">
	<pathelement location="lib\svnant.jar" />
	<pathelement location="lib\svnClientAdapter.jar" />
	<pathelement location="lib\svnjavahl.jar" />
	<pathelement location="lib\svnkit.jar" />
</path>

<typedef resource="org/tigris/subversion/svnant/svnantlib.xml" classpathref="svnant.class.path" />

<target name="svn">
	<svn username="username" password="password"> 
		<checkout url="url" revision="HEAD" destPath="path" />
		<!--<update revision="HEAD" dir="${projectPath}" />-->
	</svn>
</target>

Checkout se použije při prvním stažení, poté se neprovádí checkout, ale update.

Problém nastal u buildu aplikace. Jak již jsem zmiňoval, jako vývojové prostředí používáme Eclipse a plugin pro práci s frameworkem JBoss Seam. Tento plugin nám zajišťuje build aplikace a deploy na aplikační server. Plugin pro práci s TestNG nám zajišťuje spouštění testů – tzn. deploy aplikace na tzv. embedded JBoss a provedení testů.

Zdálo se zbytečné psát pomocí buildovacího nástroje ANT či Maven script pro build aplikace. Proto jsem se rozhodl vyhledat nástroj (plugin), který by byl schopný vzít data z Eclipse workspace a provést build. Našel jsem nástroj ant4eclipse, o kterém jsem se dočetl, že podobnou věc umí.

Po mnoha neúspěšných pokusech jsem zaslal dotaz do fóra, ve kterém jsem se ptal, jakým způsobem se provádí build Java aplikace (Seam + J2EE + JSF). Překvapivě rychle jsem dostal odpověď, že nástroj takovouto aplikaci buildit neumí. (Zajímá-li vás však build „obyčejné“ Java aplikace, určitě vám doporučuji se na nástroj podívat.)

Protože jsem žádnou další alternativu neobjevil, nezbylo mi nic jiného, než napsat vlastní ANT build script. Přesto, že jsem s ANT-em nikdy nepracoval, nezdál se být úkol až tak těžký. Podíval jsem se, jak vypadá build, který provádí Eclipse – tedy ten, který se nachází na aplikačním serveru (v našem případě to byl JBoss AS). Tohoto jsem se držel – jen tak mimochodem, již po několika desítkách minut práce s ANT-em zjistíte, proč se nástroj jmenuje ANT – je to opravdu mravenčí práce. :-)

Když už se konečně zdálo, že mám hotovo, hodně jsem se zmýlil! Sice jsem vytvořil strukturu aplikace, kterou bylo možné nahrát na aplikační server, problém však byl se spuštěním testů.

Nástroj TestNG spouští totiž testy ne přímo na aplikačním serveru, ale na tzv. embedded JBoss. Tady jsem opravdu narazil, protože jsem nebyl schopen nakonfigurovat buildovací script tak, aby úspěšně spustil embedded JBoss a provedl testy.

Prošel jsem si ukázkové aplikace k frameworku Seam a zjistil jsem, že je zde možné testy spouštět. Protože spuštění mi zafungovalo a testy se úspěšně provedly, řekl jsem si, že projdu buildovací scripty ukázkové aplikace a spustím testy obdobným způsobem. (Tady jsem si potvrdil svůj úsudek o tom, že psaní a editace build scriptů je opravdu mravenčí práce) Skutečně jsem spouštění testů nalezl, zkopírovaní a použití v naší aplikaci však bylo velice komplikované. Sada buildovacích scriptů examplů se všemožně includuje a nalézt skutečné hodnoty zástupných proměnných bylo poměrně dost náročné.

Jelikož i zde jsem narazil, napadla mě jiná možnost – použít buildovací script pro ukázkovou aplikaci Seamu na naši aplikaci. Jelikož tato ukázková aplikace má jinou strukturu, bylo nutné upravit výstup z mého ANT-ovského buildu do podoby, která bude totožná s ukázkovým příkladem Seamu.

Toto je podoba upraveného projektu do podoby, ve které jsou všechny Seam examply:

  • jboss-seam
    • bootstrap
    • build
    • classes
    • examples
      • naše aplikace
        • resources
        • src
        • view
        • build.xml // zkopírovaný ze seam examplu. Stačí provést editaci názvu aplikace a resourcu – tzn. souboru, kde se definuje URL databáze.
    • lib
    • test-output
    • ui
    • build.xml // testo soubor je přesně ten, který je v examplech, build.xml z naší aplikace pomocí něho spouští TestNG testy

Pro úspěšné spuštění testů stačí spustit build.xml (target = test) z naší aplikace:

Jen pro doplnění – vytvoření struktury, která je shodná s tou, kterou generuje Eclipse nebylo zbytečné – je možné ji automaticky deployovat do testovacího prostředí. Samozřejmě automatické spouštění scriptu je třeba nastavit na testovacím serveru.

Na závěr tedy shrnutí postupu:

  • stažení aktuální verze aplikace z SVN repository
  • odstranění předchozího buildu
  • build EJB vrstvy
  • build webové vrstvy
  • build unit testů
  • zkopírování buildu do souboru /seam/examples/nase_aplikace
  • spuštění příkazu ant -f seam/examples/nase_alikace/build.xml test
  • Přestože řešení buildu není úplně „čisté“, je použitelné. Máme tak nástroj, který automaticky testuje aktuální verzi naší aplikace. Jako odměnu pro ty, kteří dočetli až sem, si dovolím přidat trochu teorie a pojmů o testování SW, kterou jsem pochytil ve školních lavicích :-)

    Testování jednotek
  • Zaměřujeme se na malé kusy zdrojového kódu – na jednotlivé funkce.
  • Testujeme např. okrajové podmínky, cesty pro zpracování chyb,…
  • Integrační testování
  • Integrace zdola nahoru
    • spojíme nejnižší moduly
    • napíšeme řídící modul, který bude koordinovat práci mezi spojenými moduly
    • otestujeme skupinu
    • odebereme řídící modul a pospojujeme se skupinami ve vyšší struktuře
  • Integrace shora dolů
    • Vezmeme hlavní modul a maketami nahradíme nižší moduly
    • Postupně měníme makety za reálné moduly s tím, že po každém přidání modulu systém otestujeme.
    • Cílem je ověřit, že přidáním modulu nedošlo k zanesení chyby do aplikace.
    • Nevýhodou je nutnost tvorby maket modulů.
  • Validační testování
  • Slouží k ověření, že aplikace splňuje požadavky zákazníka.
  • Provádí se metodami black-box testování.
  • Do této kategorie spadají např. akceptační testy.
  • Systémové testování
  • Skupina různých testů, která prověřuje celou systémovou architekturu (HW, SW, administrátory).
  • Bezpečnostní testování (odolnost proti útokům hackerů).
  • Testování obnovy (ověření, že poruchy byly odstraněny ve smluveném termínu).
  • Zátěžové testování (sledování chování programu při velikém zatížení – tzn. simulace velkého počtu připojených uživatelů).
  • Black-box testování
  • Jedná se o testování správného provádění navržených funkcí aplikace. Ne vždy u tohoto způsobu známe všechny potřebné informace o implementaci.
  • Tento způsob testování nemusí nutně postihnout celý kód aplikace.
  • White-box testování
  • Při tomto způsobu testování známe informace o vnitřní struktuře aplikace, kterou testujeme.
  • Testujeme
    • všechny samostatné cesty uvnitř modulu
    • všechny podmínky se projdou větví s hodnotami ano i ne
    • všechny cykly
    • všechny vnitřní datové struktury
  • Na úplný závěr si dovolím jednu větu, která charakterizuje testování (rád bych citoval, ale autora věty si nepamatuji):

    Úspěšný test je takový, který objevil doposud neobjevené chyby.