Po delší době jsem měl zase čas podívat se na zoubek v mém TODO listu. Tentokrát jsem si vzal na paškál poměrně malou knihovnu s názvem Joda Time. Cílem této knihovny je reimplementace Java API pro práci s datumy a časem. Každý z nás, kdo pracuje s Javou nějaký ten čas, se tu a tam potýká s tímto těžkopádným API. Joda Time přinesl poměrně hodně nových myšlenek a stal se základem pro JSR 310, které by mělo být součástí nové Javy 7. Často na toto téma naráží i pánové z Java Posse. Co je tedy na knihovně tak úžasného? Čtěte dál …
Testování
Integrační testy spočívají v testování konkrétní kódu spolu s okolními částmi, se kterými spolupracuje. Cílem je snaha otestovat kód ve stavu, který se blíží reálnému nasazení. Obvykle takto testujeme datovou vrstvu aplikace (jelikož tam klasické jednotkové testy ztrácejí smysl – chceme přeci otestovat správné dotazování databáze, tudíž databázi k testu potřebujeme) a v řadě případů se nám nevyplatí mockovat ani na úrovni business vrstvy. Dokonce i Rod Johnson ve své prezentaci (kterou byl inspirován tento článek) zdůrazňuje důležitost integračních testů.
Hlavní problém integračních testů, u kterých máte ve spodu relační databázi je rychlost. Každý test spoléhá na nějaká data v DB – ty mohou být (a jsou) ostatními testy poškozena a proto je nedílnou částí všech testů setUp / tearDown operace, která se o tuto přípravu a uklizení stará. Jelikož jsou programátoři cháska líná a nechtějí se zabývat přípravou pouze minimální potřebné sady pro každý test, obvykle si vytvoří nějakého předka, který obsahuje setUp a tearDown, pro všechny testy najednou. Tím pádem se vždycky inicializuje kompletní sada dat a to si bere významné množství času. Odhadoval bych, že 80% času testů se stráví v této přípravě dat a pouze 20% času běží skutečné testy.
This presentation was prepared formerly for internal purposes of Norkom Technologies in Ireland by my old friend Pavel Jetenský. We appreciate that authorities of this company allowed us to make the presentation public so you can benefit from it as well. I also thank Pavel for preparing this presentation and for providing support to me with finalizing material to be published.
The training shows how to jUnit test J2EE application based on Spring and Hibernate. New unit test is created from scratch in Eclipse IDE, testing simple function for getting data from database. DB is created only in memory, using HSQL db. Training is targeted for developers with little or no experience with automated testing.
Music used: Utopia Banished – Night of the Black Wywern, Forshadowing the Endless Quest (http://magnatune.com) published under Creative Commons License
Flash presentation (recommended variant) [44:15] 46 MB
Podcast [48:42] 11,7 MB

Podcast Licence: Creative Commons
Jistě jste také už mnohokrát, stejně jako já, řešili problém, jak spolehlivě automaticky otestovat, že vaše aplikace správně odeslala email s konkrétním obsahem na konkrétní emailovou adresu. Problém je to zapeklitý a dosud jsem ho dokázal řešit jen těmito způsoby:
- udáním testovací schránky a automatickým výběrem této schránky (např. přes protokol POP3)
- vytvořením mock objektu, který mi zastoupil třídu starající se o odeslání emailu (tzn. k žádnému emailu fyzicky v testu nedošlo)
Oba dva přístupy mají svá úskalí. Ten první velmi komplikuje běh testu – musíme naprogramovat další funkcionalitu, která nám vybere emaily jiným protokolem, musíme řešit možnost, že se email někde pozdrží, musíme fyzicky nějakou schránku mít, musíme vyřešit to, jak při opakovaném spouštění testů rozeznáme, že do schránky přišel právě ten mail, na kterém v testu čekáme. Fakticky se potom často stane, že v testu samotném je víc chyb, jak v tom jednoduchém kódu, který se snažíme otestovat.
Druhý přístup je jednodušší a test s ním obvykle po vyladění spolehlivě prochází. Nicméně tento přístup nezaručuje, že v reálném nasazení,kdy místo mock objektu, bude skutečný objekt zajišťujicí odeslání emailu nedojde k chybě (např. díky tomu, že náš mock objekt nedostatečně dobře imituje chování reálného objektu).
Do této doby jsem tedy odesílání emailů ověřoval „ručně“. Automatické testy sice odesílaly emaily, ale ty šly na moji schránku a v ní jsem zkontroloval, jestli očekávaný email v očekávané době došel. Skvělá věc, když spouštíte testy ručně, ovšem horší v případě, že vám testy spouští integrační server. To se vaše schránka pěkně plní a vy stejně nemáte šanci vyhodnotit, zda je vše jak má.
Řada z vás možná už na výraz Mock testing narazila, někteří ne. Pro ty z vás, kteří Mock přístup v testování nepoužili je tento článek. Pro ostatní může být zajímavá ukázka této techniky na knihovně EasyMock.
- Co jsou to mock objekty?
Jedná se vlastně o techniku psaní určitého druhu automatických testů. V podstatě se jedná o nahrazení reálného objektu testovací fasádou, která neprovádí žádnou funkcionalitu nahrazovaného objektu – jen se jako tento objekt tváří. Místo původní logiky objektu je vloženo chování, které ve svém testu potřebujete.
Nejlepší bude teorii provázat s praxí. Pokud píšete automatické testy, jistě jste narazili na situaci, kdy k napsání jednoduchého testu musíte velmi složitě a pracně připravovat okolní podmínky. Např. testujete metodu v business objektu, který se dotazuje interně DAO objektů na data v databázi. To ale znamená, že před tím, než začnete testovat logiku tohoto business objektu, musíte připravit správná data v databázi. Musíte také zajistit, že se tam omylem nedostanou další data, která by test zhatila (např. v SELECT dotazu vrátila více řádků) a tudíž obvykle zase musíte po sobě uklízet. Ošetření okolních podmínek spuštění testu vás nakonec může stát několkrát více času, než potřebujete k napsaní vlastní testovací logiky.
Existují různé techniky, jak toto zajistit – setkal jsem se např. s použitím HSQL databáze, která byla celá v paměti a po každém testu se kompletně dropla a před novým opět vytvořila a dosadila se příslušná testovací data (tím, že se vše odehrávalo pouze v paměti byly testy velmi rychlé). Ovšem lehčí je dle mého názoru právě použít techniku mock objektů.
Při použití této techniky se soustředíte na testování pouze logiky business objektu a předpokládáte že okolní objekty fungují správně tak jak mají. Potom v našem příkladě za DAO objekty dosadíte pouze „prázdné“ ulity, které mají stejné rozhraní, ale místo vlastní logiky obsahují logiku takovou, kterou potřebujete pro vlastní test. Tzn. ve chvíli, kdy se business objekt zeptá DAO na konkrétní data, neproběhne dotaz do databáze, ale vy mu rovnou vrátíte data, která v daném testu potřebujete.
To je celý princip mock objektů. Nic víc, nic míň. Pokud se chcete dozvědět něco víc, pokračujte ve čtení.



