Testování není nástroj, ale metoda vývoje

Stále se ještě setkáváme s názory, že jednotkové testování je práce navíc a že není, kdo by ho zaplatil. Tento článek si klade za cíl poodhalit tuto techniku vývojářům a projektovým manažerům, kteří v ni nevěří, nebo neví, že dokáže výrazně usnadnit a zkvalitnit odvedenou práci.

Pohled vývojářů a projektových manažerů je často velmi zkreslený. Testování totiž chápou špatně, jako něco navíc, něco, co sníží počet napsaných funkčních řádků kódu za hodinu a prodlouží dobu vývoje aplikace. Ze začátku se to skutečně může zdát jako zbytečná práce, na výhody ovšem narazíte při prvním refaktoringu, kdy si nevědomky rozbijete zpětnou kompatibilitu a půlka testů vám zčervená. Z důvodů, které by vás nenapadly.

Jsem toho názoru, že kód nepokrytý testy je bezcenný. Od pohledu může fungovat, ale nemusí. Algoritmus, který vypadá napsaný správně, ve skutečnosti může dělat něco jiného. Výjimka se vyvolá v nesprávné situaci. Metoda vrací něco jiného, než má. Poté, co jsem začal svůj kód testovat (a díky tomu odhalil spoustu chyb), nevěřím už ani středníku na konci řádku.

Cílovou metou při psaní testů by nemělo být 100% pokrytí kódu a ani se to tak v praxi nedělá. Vývojář by se měl v testech zaměřit na očekávané chování aplikace a ne jít slepě za spuštěním všech řádků. Psát „neprůstřelné“ a několikrát delší testy, než je samotný funkční kód, vás sice může chvíli bavit, ale je to neefektivní a po vyprchání nadšení i demotivující.

Důležitým přínosem testování je motivace a změna přístupu k práci. Náročná implementace a vymýšlení architektury se střídá se snadným a rutinním psaním testů. Ty mají vypadat tak jednoduše a čitelně, aby v nich samotných nemohla nastat chyba. Tudíž se vyhněte jakémukoli větvení kódu a cyklům a názvy testovacích metod pište natolik výmluvné (a klidně i dlouhé), aby nebylo potřeba dodatečných komentářů, které v reportu nejsou vidět.

Testování lze spojit i s nějakou time-managementovou metodou, např. GTD. Musíte přerušit aktuálně rozdělanou práci a nechcete zapomenout, u čeho jste skončili a co ještě zbývá implementovat? Dopište si na to selhávající testy (třeba i s jediným řádkem $this->fail()) – nemusíte to nosit v hlavě a při návratu hned uvidíte, kde jste minule skončili.

Zatím jsem se nesetkal s tím, že by mělo velkou váhu psát testy před samotným produkčním kódem, jak to doporučuje metodika TDD, a spoustě lidí se to může rovněž příčit. Ale je důležité, aby odevzdávaný kód byl testy pokrytý. Jak a v jakém pořadí si to vývojář na svém stroji vyřeší, je na něm. Ale přístup „testy někdy dopíšu, teď se mi do toho nechce“ je špatně. Vždyť při samotném psaní produkčního kódu určitě testujete, jen takové testy nemají stálý charakter. Dumpujete si proměnné, zkoušíte na nějakém dočasném kódu (třeba ve funkci main() nebo v controlleru), jestli daná třída dělá to, co má. Jednotkové testy zavádějí stálost. Na jedno kliknutí prověříte funkčnost všeho dosavadního kódu.

Úplně nový význam to nabírá, pokud vyvíjíte webovou aplikaci a potřebujete zjistit, zdali jste např. refaktoringem modelu nevyřadili z provozu některé sekce webu. Bez testů by ověřování funkčnosti trvalo několik minut (pokaždé) a musel by ho provádět člověk, jehož práce stojí peníze. Pokud ovšem jednotkovými testy vhodně testujete controllery, máte funkčnost aplikace ověřenou i z hlediska uživatele.

Samozřejmě že testy nejsou všespásné a neodhalí všechny problémy. Pokud přijdete na chybu, ať už pohledem do zdrojového kódu anebo při jeho používání, prvním krokem by mělo být napsání testu, který danou chybu reprodukuje a ověření, že test skutečně selhává. Po její opravě a úspěšném průchodu testem získáte jistotu, že se daná chyba nevrátí, protože máte kód, který ji dokázal vyvolat a který opakovaně testuje, jestli se znovu neobjevila.

Testy mohou být zajímavé i pro projektového manažera, který podle nich může rychle zjišťovat, co tým udělal – co není otestované, tak ho nezajímá, protože to nemusí fungovat. Pokud vyžaduje nějakou další funkcionalitu, která závisí třeba i jen na implementačním detailu, její výsledek by měl být navenek poznat, aby byl otestovatelný. Prvním krokem by mělo být opět napsání selhávajícího testu a přiřazení úkolu vývojáři.

Mnohokrát se v praxi setkáme s názory, že na testování lidé nemají čas. Pokud honíte deadliny a sotva stíháte odevzdávat práci, je jasné, že na unit testy už ve vašem rozvrhu není místo (a nejspíš vám ani o kvalitu nejde). Ale vy, kdo to se svou prací myslíte vážně a chcete ji odvádět kvalitně, zkuste testování včlenit do vývoje jako jeho nedílnou součást, ta investice se vám mnohonásobně vrátí. Stačí začít!

Komentáře: 28

Přehled komentářů

na1k Jak začít?
Vrtak-CZ Re: Jak začít?
pavsyk Testy před produkčním kódem
Laethnes Re: Testy před produkčním kódem
pk Re: Testy před produkčním kódem
uf Re: Testy před produkčním kódem
Laethnes Re: Testy před produkčním kódem
Ondřej Mirtes Re: Testy před produkčním kódem
jos Re: Testy před produkčním kódem
František Kučera Testování by měl předcházet dobrý návrh
drevolution Re: Testování by měl předcházet dobrý návrh
Jakub Re: Testování by měl předcházet dobrý návrh
Břetislav Wajtr Re: Testování by měl předcházet dobrý návrh
František Kučera ekonomie
uf Re: ekonomie
pas Re: ekonomie
Rychta interface
Villlém Re: interface
Aleš Roubíček Re: interface
Mastodont Problém
jos Re: Problém
wdolek TDD a praxe ... ?
drevolution Re: TDD a praxe ... ?
jos Re: TDD a praxe ... ?
uf ja bych testoval
jos Re: ja bych testoval
uf Re: ja bych testoval
Naith Re: ja bych testoval
Zdroj: https://www.zdrojak.cz/?p=3229