středa 26. února 2014

Příběh jednoho selhání, katarze a poučení v agile vývoji

Tohle je příběh jednoho selhání, katraze a poučení našeho týmu při doručování re-brandované login a registrační stránky. Mohl bych ho volně zařadit do série, říkat že dělám agile vývoj je rozdíl oproti tomu dělat agile opravdu, ale neudělám to, protože na tomhle selhání jsme se hodně naučili a přijali pár opatření, které náš tým posunuly. Moje poznatky v tomhle článku pochází z poznámek, které jsem si stačil udělat během retrospektivy. Skoro bych řekl, že se v tomhle příběhu zrcadlí několik ukázkových problémů, a proto o něm píšu. Na tomhle selhání se všechny zainteresované složky podílely přibližně stejnou měrou a protože proběhla retrospektiva, kde jsme bez emocí pojmenovaly všechny problémy a příjmuli opatření k jejich odstranění, můžu zde o nich psát aniž by se to někoho dotklo.


Dobrý úmysl dláždí cestu do pekel

Původně jsme chtěli jenom udělat re-branding login a registrační stránky do GoodData. Designer navrhl vizuální stránky a jeden vývojář měl zmapovat flows, pomocí kterých se může uživatel dostat na login a registrační stránku. Přestože si řeknete, že login a registrační stránka je jenom jedna, existují různé kontexty, ve kterých login stránka vystupuje. Namátkou , embedované módy, potvrzení registrace ,Single Sign On a jeho selhání, vypršení autentizační session atd. Od začátku jsme se nechtěli pouštět do předělání logiky těchto flows. Nakonec nás stála tahle sranda dva měsíce práce, nevrhla na nás úplně nejlepší světlo u vyššího managementu a trochu narušila vztahy s Product Management (zkráceně PM). Zpětně viděno, nasekali jsme několik ukázkových chyb, které v dobré víře vycházely z našeho přesvědčení, že zvolený přístup je správný.


Dělejte jenom to co musíte, ani o chlup více

Když někomu řeknete, že se pustíte do re-designu něčeho, dělejte skutečně re-design a nic dalšího. My jsme se v rámci re-designu pustili do upgradu na novější verzi knihovny Ember.js, přepisu kódu na tuto technologii, budování a ladění infrastruktury pro automatické testy v prohlížeči. Jinými slovy jsme se v rámci re-designu, to jest v chápání normálního smrtelníka maximálně změny CSS a HTML kódu, pustili do splácení technologického dluhu. To nás stálo plno času, který jsme nemohli trávit na vlastní funkcionalitě. Mixování funkcionality a splácení technologického dluhu je nebezpečné v tom, že se velmi těžko odhaduje jeho pracnost a dochází k vazbě mezi doručením funkcionality a umáznutím dluhu. Navíc se to dost špatně komunikuje - "no víte, už by to dávno bylo, ale musíme tady ještě pošolíchat testovací framework, abychom mohli otestovat X. No a ještě musíme něco udělat se stabilitou těch testů, protože teď ty testy vlastně nemají vypovídající hodnotu. A kdy to bude? To se dá těžko odhadnout...". Proto jsme zavedli pravidlo: splácení technologického dluhu děláme separátně od vývoje funkcionality a nespojujeme jej dohromady s vývojem nových vlastností.


Rozděl, ale i doručuj po částech

Celou práci jsme si rozdělili na několik logických kroků, podle kterých jsme chtěli postupovat. Doručení a předání bylo plánované, jako celek ovšem! Díky tomu jsme měli reálnou zpětnou vazbu až úplně na konci vývoje tj. po několika sprintech. Ze zpětné vazby vyplynulo, že je potřeba předělat například validaci, protože nevyhovovala use case. To docela pocuchalo nervový aparát celého týmu. Celá story byla zpožděná, čili všichni cítili tlak na její doručení, a hlavně všichni už byli přesvědčeni, že jsou v cíli a místo toho následovalo další kolečko vývoje.

Mám pocit, že týmy obvykle plánují práci způsobem, že výsledek je vidět až úplně na konci. Představte si, že máte silnici po které chcete nechat projet auto a v jednom pruhu leží balvan. Tým tedy naplánuje nejdříve odstranění balvanu a potom nechá projet auto. Pokud se vám ovšem nepodaří ten balvan odvalit, ohrozíte tím to hlavní, průjezd toho auta. Opačný přístup je nechat to auto projet v protisměru - přestože jenom dočasně. To je podlě mě správný přístup. Zavedli jsme proto pravidlo sprintu: doručit vždy něco, co si může zákazník osahat - minimální produkt (doručit minimální viditelnou změny pro zákazníka).


Můj zákazník můj pán

Dalším problémem představovalo předání, kdy nebyl přesně známý zákazník dané funkcionality. Docházelo k ping pongu mezi PM a týmem. Z jedné části PM znělo: ano jdeme, a z druhé části: nejsme spokojeni, je potřeba ještě upravit to a to. Docela dost to vyostřilo vztahy, protože vývojáři nevěděli, kdo je ten hlavní s kým komunikovat změny. Velký vliv mělo předání celé funkcionality v PM oddělení, a k problémům by zřejmě nedošlo, kdyby byl od začátku do konce za danou věc odpovědný jeden člověk z PM. Zavedli jsme proto pravidlo: během plánování sprintu se všichni shodneme na tom, kdo je zákazník - pro koho pracujeme.

< h3>Jedno prostředí

Vlastní předvádění zákazníkovi nám komplikoval fakt, že různé části měli vývojáři ve svých větvích. Demo a verifikace probíhala vždy na lokální verzi na stavu code base, kterou měl vývojář k dispozici. Při vlastním předvádění si zákazník nemohl vyzkoušet funkčnost jako celek. Pokud se někdo objevila chyba, nebylo zřejmé, jestli je to aktuální problém a nebo to je již v jiné větvi u jiného vývojáře vyřešené. Pro zákazníka je klíčové, aby měl jedno referenční prostředí, na kterém dochází k předání a kontrole odvedené práce. Zavedli jsme proto pravidlo: na akceptačním prostředí se dohodneme během plánování. Komplikovaný merge a chyby, které se projevily až po zamergování do hlavní vývojové větve, byly násobené změnami v infrastruktuře viz upgrade Ember.js. Asi by nám pomohl mainline development (integrační problémy jsou viditelné ihned), ale na to by bylo potřeba vyřešit procesní věci spojené s plněním Service Organization Controls 2.


Neznámé neznámo

Docela dost času jsme strávili analýzou existujícího kódu, abychom zjistili stavy, při kterých dochází k přechodu na login a registrační stránku. Vznikly flows, které nám měly pomoci pochopit, kam je potřeba šáhnout, protože jsme nejenom re-brandovali, ale přepisovali inkriminované části na novou technologii a psali nové testy. Ne že by nám flows nepomohly, ale to co přinesly neodpovídalo investovaným nákladům. Neodhalily například krajní případy, ze kterých na nás během manuálního testování vypadlo větší množství chyb. Analýza nám určitě pomohlo pochopit, co všechno budeme muset otestovat, ale z pohledu odhadu pracnosti byl její přínos zanedbatelný. Shodli jsme se na tom, že mnohem více by nám pomohl opačný přístup - začít z jedné vody na čisto s minimálním produktem případně s variantou v podobě funkčního prototypu, který je rychlejší a poukáže na problémy stejně dobře. I prototyp totiž můžete někomu ukázat a nechat ho ošahat. Analýza jsou slova a slova jsou vítr jak věděl Jon Snow a sním všichni čtenáři pentalogie Píseň Ohně a Ledu. Prototyp lépe pomáhá odhalit problémy, které by vás během analýzy nemusely napadnout - neznámé neznámo, nevím že existuje proto jej ani nemůžu analyzovat.



Strategie

Žádný plán nepřežije první dotek s nepřítelem, jak pravil von Moltke, to ale neznamená, že by neměla existovat strategie, jak řešit situace se kterými ze začátku nepočítám. Ve chvíli kdy se objevily nějaké problémy, neexistoval postup jak se z nich vymotat. Strategie může být: "dodávám malé kousky, které na několikadenní bázi ukazuji zákazníkovi. Změny přijímáme operativně na základě trvalé zpětné vazby ze strany zákazníka. Pokud se najde problém, který nedokážeme vyřešit z časových důvodů nebo je to velká změna do zadání, vyřešíme to během dalšího sprintu jako navazující úkol." My jsme žádnou strategii neměli, protože celý úkol byl pojatý jako monolit na všech úrovních - plánování, vývoj, testování, předání atd. Strategie, a teď myslím strategie vývoje té vlastnosti, by nás mohla donutit snažit se ten monolit rozsekat již při plánování.


Závěr

Když to shrnu do pár základních pravidel, na kterých jsme se shodli na základě retrospektivy.

  • Doručujeme něco viditelného co si může zákazník ošahat v každém sprintu
  • Během plánování zná celý vývojový tým, kdo je zákazníkem resp. kdo hraje jeho roli
  • Při plánování určujeme strategii vývoje tj. teď uděláme X a další sprint Y
  • Neděláme detailní plán, protože stejně nepřežije první dotek s realitou
  • Při plánování se zákazníkem dohodneme na akceptačním prostředí
  • Nemícháme infrastrukturu do vývoje nových vlastností