2. 12. 2014
Pro uvedení do kontextu stručně k tomu, jak u nás v LMC vývoj probíhá. Vyvíjíme naše vlastní webové produkty prostřednictvím několika agilních týmů. Průběžně tak dochází v aplikacích k množství změn, na úpravách jedné aplikace pracuje souběžně několik vývojářů z daného týmu, a to v rámci různých a často nesouvisejících issues (ticketů). Produkty jsou to rozsáhlé, mají za sebou několikaletý vývoj, a je tak téměř nemožné, aby některý vývojář znal nazpaměť všechny části aplikace.
Aplikace jsou samozřejmě do rozumné míry pokryté unit testy. Každou issue před dokončením testuje kromě samotného vývojáře v rámci code-review obvykle alespoň jeden další vývojář, stejně tak funkčnost kontroluje ještě produktový manažer. Jenomže – ani jedna z těchto vrstev testování nemusí odhalit některé problémy. Zvláště ty, které se zdánlivě vůbec netýkají upravované části aplikace. Jak to? Může napovědět pár příkladů, ať už z naší praxe či teoretických:
Podobné „rozbíjení“ aplikací je víceméně přirozenou a nevyhnutelnou součástí vývojového procesu. Důležité ale je umět tyto problémy účinně a co nejdříve nacházet.
Cestou k tomu je systémové testování, konkrétně jeho funkční část (proto „funkční systémové testování“). Tedy testování, které probíhá nad celým již integrovaným systémem a které testuje nějaký funkční požadavek či očekávání. Jedná se tedy o vrstvu testů, která je nad unit testy a těsně nad integračními testy. Svým způsobem se tak jedná o výstupní kontrolu produktu před jeho předáním zákazníkovi. (U nás děláme vlastní produkty, takže máme tzv. „interního zákazníka“ – stakeholdery, nicméně na podstatě to nic nemění.)
Na straně zákazníka by pak mohlo následovat ještě akceptační testování, tedy testování, zda aplikace splňuje např. smluvně zadané funkční scénáře. Na rozdíl od akceptačního jsou ale při systémovém testování ověřovány i různé podscénáře, chování, které zákazník očekává (a nemusí být ani ve specifikaci) a celková bezporuchovost dané webové aplikace. A jak bylo uvedeno výše, má navíc automatizace tohoto testování neocenitelnou hodnotu v průběhu vývoje. Funkční testy jsou tedy nezbytnou součástí fungujícího continuous integration – vrchol testovací pyramidy.
Laicky se dá v případě webu funkční systémové testování označit jako „klikací testy“, protože o tohle převážně jde. V prohlížeči – ať již skutečném (např. Firefox) nebo v headless (PhantomJS) – se automaticky projde nějaký scénář a podobně jako v unit-testech se zkontroluje, že očekávané chování odpovídá tomu, které skutečně nastalo. Může se jednat o podobně jednoduché scénáře s jednoduchými očekáváními:
Pokud bychom kontrolu podobných scénářů dělali ručně, zabralo by nám to spoustu času. To by kromě nákladů a zdržení nasazování (když se najde a pak opraví chyba, je třeba celou aplikaci opět přetestovat) znamenalo, že bychom ji ani nemohli testovat průběžně, a na chyby bychom přicházeli až v okamžiku „těsně před předáním“. A jak známo, čím dříve chybu najdeme, tím nás stojí méně.
Pro automatizaci tohoto testování dnes existuje řada nástrojů. Některé jsou postavené pouze nad jedním headless prohlížečem (Casper JS a další), čímž mimo jiné testerům ztěžují psaní i kontrolu testů. Jiné možná zbytečně přidávají vrstvu abstrakce (Behat + Mink) a pro funkční testování se vlastně ani nehodí.
Po špatných zkušenostech s proprietárním nástrojem Squish jsme se letos rozhodli přejít na Selenium WebDriver (mimochodem – WebDriver se stává W3 specifikací a tedy de-facto průmyslovým standardem pro automatizaci ovládání prohlížečů).
Testy píšeme v PHP (kde používáme implementaci php-webdriver), a spouštíme skrze vlastní nástroj Steward postavený na PHPUnitu. O jejich automatické spouštění oproti různým vývojovým prostředím se stará Jenkins CI server. Samotné Selenium pak testy vykonává ve Firefoxu, Chromu, PhantomJS a zkoušeli jsme i MSIE. I přes určité porodní bolesti se nám to zatím vcelku osvědčuje, což dokládá mimo jiné i snížení množství WTF za minutu při psaní a kontrole testů (v porovnání s předchozí platformou).
Ve chvíli, kdy neděláte jenom aplikace zakázkovým low-end stylem „nasadit, vyfakturovat a zapomenout hesla k ftp“ ale naopak se k aplikaci vracíte, nebo se třeba jako v našem případě jedná o vlastní vyvíjené produkty, byl by život bez systémového testování hodně na hraně. Testy se dají rychle napsat i spustit a z praxe musím říci, že nám zachránily řadu i velmi vážných produkčních incidentů.
(Autorem úvodního obrázku je NATO a podléhá licenci CC-BY-2.0)
Ondřej Machulda