fbpx

Ako nazývať testy?

Kedysi dávno som pracoval na projekte, kde bolo požadované pokrytie testami na 80%. Celkom fajn hodnota, taká dosiahnuteľná. Súčasťou bola aj príručka Coding Standards, kde začal môj problém. Kapitola o unit testoch požadovala, aby existoval jeden test pre testovanú metódu. Problému s týmto prístupom som sa venoval v Testujte len jednu vec.

V tomto článku sa chcem venovať druhému problému z našej príručky — mená testov. Príručka žiadala, aby meno testu bolo tvorené takto: testMethodA, respektíve ak bolo treba pridať viac testov, tak takto: testMethodA_2 — nič nehovoriace meno, čo vlastne test robí. Len naznačí, že volá tú metódu. Ani zmienka o tom, prečo má zmysel volať tú metódu. Snáď prečítaním tela testu na to prídeme. Ale čo ak čítaním prídeme na to, že sa volá viac metód?

Každý test testuje iný scenár

Skúsme sa pozrieť na test ako špecifikáciu, čo má komponent robiť. Ako prvé čo nám napadne je, že špecifikácia by mala byť jasná už z mena metódy. Nechceme tú informáciu dolovať z 15 riadkov kódu. A už vôbec nie zo 147 riadkov.

Ak akceptujeme, že meno testovacej metódy nám má prezradiť, o čom ten test je, tak potom by mal test testovať len jeden scenár — postupnosť volania nejakých metód. Ak by mal test testovať viac scenárov, tak nedokážeme vymyslieť dobré meno.

Tip: Ak nevieme vymyslieť dobré meno pre test, tak asi robí príliš veľa.

Gramatika jazyka nebola vymyslená zbytočne

Poďme ďalej a skúsme si predstaviť aké by to bolo, keby slovenčina nemala stanovené gramatické pravidlá. Každý by mohol povedať svoju vetu inak. Nedorozumenia by boli na dennom poriadku, lebo druhí ľudia by mohli pochopiť tú náhodnú permutáciu slov inak.

Alebo čo keby sme sa vyjadrovali len heslovite? „Hlad.” A teraz skúste uhádnuť či som hladný, píšem o včerajšom zážitku z reštaurácie, alebo sa obávam, že ste pri čítaní tohto textu vyhladli.

Videli ste vo vašom projekte mená testovacích metód, čo pripomínajú jednu z uvedených možností? Boli ste s takým menom spokojní? Ak nie, poďme nazývať naše testy lepšie.

Tip: Keď potrebujem zistiť čo test robí, vždy si najprv prečítam jeho meno. A potom sa snažím overiť, či implementácia testu zodpovedá jeho názvu. Malo by to ísť ľahšie, lebo už mám v hlave mentálny obraz a očakávania.

Ako to robím ja

Doteraz som mal šťastie, že som robil len na projektoch, kde bol celý kód a aj doména po anglicky. Takže som nemusel riešiť diakritiku v menách metód. A ani tu nechcem. To je dôvod prečo všetky referencie na kód mám v angličtine. Dúfam, že to nevadí.

Na všetky moje testovacie metódy používam nasledovnú šablónu — anglická veta bez podmetu. Napríklad:

shouldCalculateAverageTemperatureForSequenceOfInputValues

Je to ľahko čitateľné a keďže poznáme gramatické pravidlá angličtiny, tak by sme si hneď mali spraviť predstavu o tom čo test robí. Súčasne to znie ako špecifikácia čo sa od komponentu očakáva.

Prečo mi chýba podmet? Veď takto to nie je gramaticky správne. Áno, ja viem. Je to taká programátorská vlastnosť — snaha vyhnúť sa opakovaniu toho istého. Unit test by sa mal venovať testovaniu len jednej triedy. Takže mená všetkých testovacích metód by začínali tým istým slovom (menom triedy). A navyše sa to meno nachádza v názve testovacej triedy. Preto ho vynechávam a čitateľnosť tým netrpí1.

Tip: Keď sa nám nedarí vytvoriť gramaticky správne meno, je možné, že daná funkcionalita nepatrí do tohto komponentu, ale do niektorého iného. Napríklad by mala byť metódou niektorého parametra.

Občas sa mi stane, že začnem písať nový test, ale ešte nemám jasnú predstavu o tom, aké metódy na to potrebujem, prípadne ako sa dostanú ku dátam (parametre, cez mock, …). Aby som prekonal writer’s block, tak používam nasledujúcu fintu:

Tip: Keď na začiatku písania nového testu neviem vymyslieť dobré meno, tak najprv napíšem telo testu a meno doplním dodatočne. (Test-Driven Naming? 😉)

Sú aj výnimky?

Každé pravidlo by malo mať aspoň jednu výnimku, nech stojí za to. V mojom prípade to je táto:

shouldCalculateAverageTemperatureForSequenceOfInputValues_test1

shouldCalculateAverageTemperatureForSequenceOfInputValues_test2

Na konci mena testu je niečo, čo nezapadá do konceptu anglickej vety. Tento prístup používam v prípade, že testujem presne to isté ale s inými parametrami. Keby som mal vysvetliť v mene testu, že jediný rozdiel medzi nimi sú trošku iné údaje, tak sa meno skomplikuje a to nestojí za problémy so zníženou čitateľnosťou.

Nevedie to k príliš dlhým menám metód?

Mám takúto príhodu. Kolega sa ma raz spýtal: „Palo, čo si myslíš o 64 znakovom mene metódy?”
Ja som sa zamyslel a povedal som: „Hm, to je dosť dlhé meno. To nie je moc dobré. Jedine že by to bol unit test a to meno vysvetľovalo, čo test robí”.
Na čo on s úsmevom reagoval takto: „Vidím, že si konzistentný. Je to tvoj test.”

Dlhé mená metód v testoch nevadia. Nikde sa na ne nemusíme odkazovať, lebo jediný kto ich volá je JUnit. Takže kľudne napíšte dlhé meno metódy, nech plní aspoň nejaký účel. Kvalitné meno testu je užitočnejšie ako Javadoc na testovanej metóde.

Záver

Je fajn, že kód je určený pre počítač. Ten sa z neho vyzná a je mu jedno čo robí a ako vyzerá. Ale my, programátori, ho musíme čítať tiež. A nám to nie je jedno, či vďaka jeho nepochopeniu strávime na oprave chyby 15 minút alebo celý deň.

Takže keď umožníme ľuďom aby rýchlo pochopili kód, tak ich život bude lepší. A dôsledné nazývanie testovacích metód je prvý dobrý krok k tomuto cieľu.


  1. Kedysi existoval plugin do Intellij IDEA, ktorý vedel vypísať zoznam všetkých metód, ale takým spôsobom, že rozdelil slová a vznikol krásne čitateľná špecifikácia komponentu. Volal sa TestDox, možno ho raz niekto oživí.

2 komentáre k “Ako nazývať testy?”

Nie je možné pridávať komentáre.