pondělí 29. července 2013

Když je během vývoje intuice špatným rádcem - release a testy

Během vývoje máme občas tendence řídit naše rozhodnutí intuicí, bohužel ne vždy je to dobrý rádce a občas je lepší dělat pravý opak. Vybral jsem několik příkladů kdy je lepší se intuici vyhnout. Většinou se jedná o příklady spojené s releasováním a testy.

Četnost releasů

Problém: release je velmi křehký a bývá sním spojeno plno problémů

Intuice: snížme četnost releasů. Je bezpečnější vystavit se těm problémům jednou za tři měsíce než každý měsíc.

V tomhle případě je docela zřejmé, že nám prodloužení releasovacího okna moc nepomůže. Problémy, které jsou s releasem spojené, nám nikam nezmizí. V horším případě se naopak nakumulují. Pokud releasujete větší celek je složitější dohledat případnou příčinu problému. Dalším poměrně nepříjemný problém představuje rollback. Čím větší je releasovaný celek, tím víc toho musíme odstranit a tím komplikovanější proces to je. Navíc rollbackem přijdeme úplně o všechny změny. Intuice je v tomhle případě špatný rádce, dělejte přesný opak if it hurts do it more ofter. Většina problémů s častým releasem vychází z nedostatečné automatizace celého releas procesu a nebo přílišné závislosti na manuálních testech.

Právě manuální testy resp. jejich doba by měla ze začátku udávat takt releasování. Jestliže potřebujeme manuálně otestovat aplikaci a trvá nám to týden, pak bychom se měli snažit ze začátku o přibližně týdenní releasovací cyklus. Zároveň bychom se měli snažit tyto testy postupně automatizovat. Můžeme si dovolit přístup chytré horákyně a zvýšit frekvenci releasů tím, že ne pro všechny změny jsou manuální testy potřeba a manuálně otestovat jenom část aplikace. To platí v případě, kdy nám chybí jenom část automtických testů a nebo jejich pokrytí není dostatečné.


Build/release procesu

Problém: release/build musí být být přehledný a pochopitelný

Intuice: pojdmě release zdokumentovat, potom ho může každý udělat

Tohle není primárně protiargument intuice, ale jakákoliv dokumentace zastarává od okamžiku kdy je vytvořena. Měli bychom se snažit celý proces automatizovat bez ohledu na to, jestli je to build a nebo release. Dokumentace by měla popisovat high level koncept/design (co), ale nikoliv vlastní provedení (jak). Jak se praví v eposu Píseň Ohně a Ledu (v seriálovém provedení Hra o trůny): slova jsou jenom vítr. Oproti tomu více či méně přehledný kus kódu automatizující cokoliv je právě tím jediným a autentickým zdrojem pravdy. Další nevýhoda dokumentace tkví v kontextu. Dokumentace, kterou bude psát člověk, který zná danou věc dokonale, bude vypadat jinak než dokumentace, kterou budete psát s vědomím toho, že čtenáři bude chybět kontext. Pokud někomu napíšete proveďte restart služby XYZ, předpokládáte že člověk ví, kde se ta služba nachází a jak ji restartovat. To člověk může udělat několika způsoby, počínaje kill -9 přes shell skript až po prostředky operačního systému. Přitom služba resp. pisatel dokumentace očekává, že se použije přesně jeden konkrétní a vůbec ho nenapadne, že by to člověk dělal jinak. Přesně to je kontext, který se zachycuje velmi těžko a je uvozen zkušenostmi toho, kdo dokumentaci píše a používá. Jinými slovy je to na vodě. To je další důvod, proč se vyplatí spoléhat na automatizaci místo dokumentace.


Testování až po implementaci

Problém: testování je drahé

Intuice: testujme až na konci, abychom drahý krok neopakovali

Tenhle argument nepostrádá jistou logiku, pokud by ovšem neplatilo, že čím déle se chyba najde, tím větší náklady jsou na její odstranění. V kombinaci s málo častými releasy je to doslova jako sedět na sudu se střelným prachem s odpáleným doutnákem. Představte si, že najdete závažnou chybu těsně před releasem, který je naplánován jednou za šest měsíců. Tahle intuice je opět důsledkem nedostatečné automatizace testovacího procesu. Platí přímá úměra: čím více automatických testů, tím častější zpětná vazba a odhalení potenciálních problémů. Pokud jsou manuální testy nákladné, je potřeba se zamyslet nad tím, jak jejich penzum snížit a vyvážit je testy automatickými. Samozřejmě není to zadarmo a náklady na udržování automatických testů pro UI mohou být drahé. Obzvláště pokud dochází neustále ke změnám nebo neexistuje dostatečná abstraktní vrstva (testovací DSL), která test odstiňuje od low level implementačních detailů.

Cenu má i testování neúplné implementace. Části systému, které nejsou k dispozici, nahradíme mockem. Sice nemáme systém kompletní z pohledu implementace, ale je kompletní z pohledu funkcionality. Můžeme na něm vyzkoušet určité vzorce chování uživatelů. Pokud s testováním otálíme, můžeme mít na konci sice implementačně kompletní funkcionalitu, která ovšem nebude dávat smysl z pohledu uživatele a nebo bude mít špatnou použitelnost. Pokud nám test po první třetině implementace ukáže, že je celá funkcionalita k ničemu, můžeme jí zahodit a investovat zdroje do něčeho jiného a nebo jí upravit, aby dávala smysl. Testy a teď myslím jakékoliv testy jsou lakmusovým papírkem, který indikuje kvalitu a poskytuje zpětnou vazbu, která je při vývoji kritická.


Nestabilní automatické testy

Problém: testy často padají

Intuice: výsledky testů ignorujeme nebo defektní testy úplně smažeme

Nestabilní testy představují mor. Přestože nám intuice říká: pojďme je ignorovat, nedělejte to. Potíž s testy, o kterých řeknete: "Ano tenhle test občas padá", je v tom, že když začnou padat doopravdy, vy na to nepřijdete. Mimo jiné to znamená, že musíte nějak kontrolovat, že to je očekávané selhání. Další problém spočívá v tom, že to je nepřehledné. Pokud vám dlouhodobě neprochází 5 ze 100 testů ještě to neznamená, že to je jedna a ta samá pětice. Ignorování testů vede k menší ostražitosti, která přechází v letargii. Pokud jsou nějaké testy nestabilní, například protože závisejí na službách třetích stran, je potřeba refaktoring. Často se jedná o ne úplně vhodně napsané testy, kde se místo integrace testuje služba třetí strany. Pokud je test dobře napsán a přesto je nestabilní, lze udělat speciální strategii spouštění toho testu. Tuším, že jsem to viděl v prezentaci Continuos testing v Google, nestabilní testy se několikrát zopakují. Nestabilní testy mají re-try strategii, která naplánuje spuštění testu po určitém intervalu.


V tomto článku jsem vybral několik příkladů, kdy se vyplatí jít proti intuici. Určitě vás napadnou nějaké další a já budu rád, pokud se o ně podělíte v komentářích.