Automatizované testování JavaScriptu

Testy, které se krkolomně spouští, zobrazují nepřehledně výsledky nebo běží pomalu, budete spouštět málo a nakonec je přestanete psát. V článku pojednáme o tom, jak dosáhnout přesného opaku pomocí programu JsTestDriver. Ten umožní, aby se vaše javascriptové testy spouštěly snadno (třeba při každém uložení souboru v IDE), běžely rychle a navíc v několika prohlížečích najednou.

Cíl

Představme si, že jsme se rozhodli testovat náš javascriptový kód a nyní stojíme před problémem, jak tyto testy zautomatizovat při samotném vývoji a při integračních buildech.

Nejprve si definujme, jaké požadavky na testování v JavaScriptu máme. Ve zbytku článku vám potom podrobně ukážeme jednu z cest, jak tohoto cíle dosáhnout.

  1. Testy chceme spouštět při každém uložení změn v kódu a nechceme přitom opouštět prostředí IDE. Výsledky testů chceme také vidět přímo v IDE.
  2. Chceme, aby se testy spouštěly a vyhodnocovaly při každém automatickém buildu na integračním serveru.
  3. Ať už pracujeme stylem TDD nebo ne, musíme testy rádi spouštět. To znamená, že testy musí proběhnout rychle (do 1 sekundy).
  4. Prostředí, ve kterém testujeme, musí mít dostupné javascriptové API prohlížeče. Nelze tedy jako běhové prostředí použít Node.js.
  5. Požadujeme maximálně jednoduchou konfiguraci pro celou sadu testů.

Překážky u většiny testovacích frameworků

Existuje spousta testovacích frameworků v JavaScriptu, které se liší svým jazykem a frameworkem mocků a stubů, málokterý však řeší uvedené první dva požadavky.

mock – objekt, který simuluje chování skutečného objektu a zná očekávaná volání.
stub – simuluje či nahrazuje chování části testovaného kódu (v JavaScriptu zpravidla funkce).
spy – monitoruje volání funkce (počet, parametry, návratové hodnoty).

Mnoho z nich spouští testy přímo v okně prohlížeče, čímž zajistí kromě prostředí pro běh samotného JavaScriptu i API prohlížeče. Má to však podstatné nevýhody:

  • Kromě samotných testů totiž musíme vytvořit HTML soubor, který načte do prohlížeče veškerý testovaný kód.
  • Při spouštění testů se vývojář musí přepnout do prohlížeče, obnovit stránku a počkat na výsledky.
  • Zautomatizovat takové testy pro continuous integration bude obtížné například proto, že výsledky zobrazené v prohlížeči jsou dobře čitelné pro člověka, ale ne pro stroj, navíc se k nim nelze přímočaře dostat.

Další nevýhodou je, že během vývoje testujeme jen v jednom prohlížeči na jedné platformě a o chybách v jiných prohlížečích (platformách) se dozvíme až při automatickém buildu na integračním serveru, a musíme se tak vracet k již odladěnému kódu.

Při každém uložení změn kódu v IDE chceme okamžitě vědět, zda testy procházejí. To znamená, že prohlížeč(e) musí být již spuštěné a nesmíme se zdržovat přepínáním do nich a obnovováním stránky s testy, což je pomalé, protože se musí znovu načíst vykonat všechen produkční kód. Nemluvě o tom, pokud máte pro každý test case samostatný HTML soubor. Pouze výjimečně svědomitý vývojář bude takové testy spouštět.

Řešení

Stejné problémy řešili před několika lety vývojáři v Google a napsali program JsTestDriver, který se je snaží univerzálně řešit. Existují i další nástroje, například pro Mocha framework existuje projekt mocha-phantomjs, který umožňuje pouštět Mocha testy v PhantomJS, což je WebKit jádro s kompletním javascriptovým API.

Hledáme PHP a javascriptové vývojáře pro naše projekty. Kontakt michal.illich.cz.

Jak funguje JsTestDriver

JsTestDriver je malý program napsaný v Javě, který otevře HTTP službu na určitém portě (budeme jí dále říkat server). K němu se po startu připojíte z libovolně mnoha prohlížečů z libovolných platforem včetně mobilních. Můžete rovněž JsTestDriver nakonfigurovat, aby si prohlížeče otevíral sám.

Stránka otevřená v prohlížeči se stává „otrokem“ serveru, který do ní nahrává potřebný javascriptový kód (při jejich pozdější změně, pak už nahrává jen změněné soubory). Testy se spouští jednoduše z příkazové řádky, JsTestDriver obstará spuštění testů paralelně ve všech prohlížečích najednou. Prohlížeče následně odešlou výsledky testů zpátky serveru a ten vám je pak zobrazí na standardním výstupu nebo je uloží do souboru (v XML JUnit formátu). Kromě toho si můžete nechat zobrazovat i výstup konzole prohlížeče.

Vzhledem k tomu, že se při jednom běhu testů většina kódu nemusí ani parsovat a že javascriptové API je neblokující, jsou testy velmi rychlé, JsTestDriver vykoná řádově stovky testů na sekundu.

Díky jednoduchému rozhraní není problém spouštění testů v JsTestDriveru integrovat do vašeho IDE (pro Eclipse existuje i plugin) nebo do automatických buildů.

Jako konfigurace stačí seznam souborů, které se mají načíst, ve formátu YAML. Například:

load:
  - lib/jasmine/jasmine.js
  - lib/jstestdriver/JasmineAdapter.js
  - src-js/jQuery/*.js
  - src-js/app/*.js

test:
  - tests/js/unit/*.js 

Podívejte se, jak JsTestDriver vypadá v akci.

Z vlastní zkušenosti mohu potvrdit, že nasazení JsTestDriver pro automatické testování na našem integračním serveru bylo snadné, přestože testy nepouštíme v klasickém prohlížeči, ale v PhantomJS. Výstup výsledků v XML JUnit formátu, podporuje snad každý (i náš) integrační server.

Další výhody

JsTestDriver není další asertovací framework, můžete klidně zůstat u svého, pouze spouští vaše testy a reportuje výsledky. Nicméně, aby pochopil výstup vašeho frameworku, potřebujete použít adapter. Takové adaptery existují pro:

V neposlední řadě JsTestDriver umožňuje pomocí pluginu generovat report o code coverage.

Shrnutí

Ukázali jsme, jak je možné zautomatizovat testy pomocí JsTestDriveru.

  • JsTestDriver umožňuje spouštění testů nad farmou prohlížečů různých platforem.
  • Testy jsou velmi rychlé, protože běží paralelně.
  • Můžete i nadále používat svoji oblíbenou knihovnu na unit či scenario testy.
  • Snadno se konfiguruje a umí i generovat code coverage report.

Cíl splněn. Pokud to děláte jinak, budeme rádi, když to sdělíte v diskusi.

Zdroje

Komentáře: 6

Přehled komentářů

michal diky za skvelej souhrn
Peter zaujimave
Aichi Spousteni JS Unit testu
Martin Hassman Re: Spousteni JS Unit testu
Jan Bílek Alternativa: Testacular
Jan Prachař Alternativa: Buster.JS
Zdroj: https://www.zdrojak.cz/?p=3730