Pár triviálních poznámek k vývoji aplikací

Zdroják by měl přinášet nejen informace o nových technologiích a webových kouzlech. Rádi dáváme prostor i článkům, které se věnují metodice práce, „správným návykům“ při vývoji a podobně. Článek Reného Steina shrnuje takové zásadní věci, které by si měli pamatovat především vedoucí vývojových týmů…

Disclaimer: Tento článek vznikl jako rozšíření spotu na blogu a spot na blogu obsahoval jen odpověď na e-mailový dotaz, z něhož byly odstraněny všechny identifikační údaje firmy, která se ptala na některé praktiky a doporučení související s (re)organizací vývoje. Článek obsahuje v titulku záměrně slovo triviální. Když se vám, milí čtenáři, bude zdát, že píšu o trivialitách a záležitostech, které přece “všichni znají”, nemusíte mi to psát znovu v komentářích, protože jsem rád, že jsme se shodli. :) 

V původním e-mailu jsem odpovídal na dotaz, jak si poradit s odstraňováním chyb u starší a rozsáhlé aplikace. Když jsem odepisoval, uvědomil jsem si, že sepisuju jakési “triviální desatero vývoje”, které se snažím už dlouhou dobu svému okolí vtloukat do hlavy. I když jde o triviální zásady, budu příště odkazovat raději na tento článek, než abych vše opakoval pokaždé znovu. Jméno firmy je v textu nahrazenou souslovím „anonymní firma“.

1. Zrušte hranice mezi lidmi

Máte ve své firmě samostatná oddělení pro analýzu, vývoj a testování aplikací, která se vzájemně nesnášejí a lidé v nich se obviňují, kdo za jako průšvihy na projektech může? Je nutné zrušit umělé hranice mezi analytiky, vývojáři a testery i dalšími projektovými rolemi. Žádná výměna informací jen přes šéfy oddělení nebo pověřené osoby.

Máte šablonu, do níž se musí formálně zapisovat požadavky od zákazníka, kdy se do správných kolonek v šabloně nedokáže trefit už ani otrlý státní úředník po 20 letech byrokratické praxe? Slouží tahle dokumentace skutečně vývoji, nebo jen plníte nějaké ISO normy a ukájíte potřeby narušeného člověka, který se měl stát spíš hloubavým archivářem, prohrabujícím se s rozkoší zetlelými listy papíru, než člověkem odpovědným za použitelné zadání a „živou“ dokumentaci projektu?

  • Vytvořte malé sebeorganizující týmy odpovědné za určitou část projektu (nastálo, nebo do dalšího releasu). V čele bude team leader, který garantuje kvalitu. Team leader je k dispozici i testerům a řeší nesrovnalosti v analýze a systémovém designu. S dalšími team leadery řeší problémy integrace různých částí projektu. Team leader ale stále většinu času kóduje, není to embryo vychovávané pro střední management. Pamatujte, že stále platí stará vývojářská moudrost – chcete-li zničit kvalitního vývojáře, polechtejte jeho ego, slibte mu manažerskou sesli… a pak ho do ní skutečně posaďte!
  • Koketovali jste jemně s psaním automatických testů, ale když jste poznali jejich časovou náročnost, řekli jste si, že se bez nich obejdete a budete raději psát produkční kód, který alespoň něco zákazníkovi přináší? Skutečně jste na tom tak dobře, že na projektech netrávíte spoustu času řešením zbytečností a že zrovna testy pro vás představují největší časovou zátěž? Dovolím si nesouhlasit.
    Co mítink, na kterém se půlden (ve firmách s mnoha úrovněmi řízení a ani jedné úrovně s odpovědností dokonce celý den) řeší, jak předejít tomu, že posuneme datum nasazení projektu, aby se poté na konci dne do zápisu ze schůzky vítězoslavně napsalo, že po vyčerpávající (to není lež, na konci jsou většinou účastnící z tak neproduktivního dne a manažerského newspeaku odvařeni podobně jako nedobrovolní posluchači několikahodinového projevu Fidela Castra blahé paměti) analýze projektových problémů, zoufalého slibování “benefitů” vývojářům (za to, že z manažerského prstu vycucaný časový harmonogram se stane na tomto projektu poprvé realitou) a po odvážných pokusech najít jiné řešení se nasazení projektu skutečně posouvá na pozdější termín.
    Za každý zrušený mítink napište jako poděkování všem milostivým projektovým bohům 100 testů a za každý takový absolvovaný mítink jako mentální očistu napište ještě večer po jeho ukončení alespoň 5 testů. Ocení to zákazníci i vaši kolegové ještě v době, kdy si na proběhlé mítinky ani zápisy z nich už nikdo nevzpomene.

2. Objevená chyba musí skončit napsaným testem

Na každou objevenou chybu musí být napsán automatický test, který zajistí, že chyba neprobublá do dalších releasů. Bez toho žádné (ani shora seslané) organizační opatření za účelem vymýcení chyb v aplikaci nefunguje. Bez napsaného testu se chyba nepovažuje za odstraněnou, ale jen za náhodou se nyní neprojevující. Máte napsanou rozsáhlou aplikaci, testy byste pro ni napsali rádi, ale nevíte, kde začít a řídíte se pravidlem, že do kódu raději nezasahujete, dokud to není nutné?

Hnije něco v jádru systému, který psal kolega, co již emigroval do jiné firmy, takže nikdo neví, kdy se systém zcela rozpadne, a všichni doufají, že to bude v době, kdy budou také pryč z firmy, nebo alespoň poté, co zákazník zaplatí přepsání? Pak začněte přesně tímto bodem – na objevené chyby napište testy! Moc času vám to nezabere a alespoň neabsolvujete tolik trapasů, kdy zákazník říká, že chyba, kterou nahlásil před půl rokem a kterou jste v nějakém hotfixu opravili, se do aplikace po novém releasu opět vrátila. I moře je z kapek a rozsáhlé balíky testů na projektu jsou složeny z jednotlivých testů napsaných třeba dodatečně po výskytu chyby v aplikaci.

3. Automatizujte testování

Je třeba postupně napsat velké množství automatických testů (unit, integrační, akceptační) tak, aby se testeři věnovali hlavně novým záležitostem v releasu a aby vývojáři ani testeři nebyli obětí „ručně prováděných“ regresních testů, které mají formu nikdy nekončícího debugování. Tím se i zkrátí doba, kterou „anonymní firma“ nutně musí trávit opakovaným debugováním a „ručním“ nalézáním příčin chyb.

Nemám nic proti debugování, ale skutečně věříte tomu, že u jen trochu rozsáhlejší aplikace budete schopni před každým releasem odkrokovat všechny větve svého kódu? Nebo už jste ve fázi, kdy si říkáte, že “oddebugujete” jen ty hlavní větve kódu, protože ostatní nestíháte, a spoléháte na to, že zákazník důsledky vašeho šlendriánu ponese tiše a s pokorou?

Automatizované testy představují práci, která se na projektech vyplatí, a navíc jde i o mnohem levnější řešení problému, než nabírání dalších a dalších testerů. Tím nechci říci, že testeři-klikači (míněny živé osoby) nemají na projektech místo. Mají, a důležité – tester-klikač odhalí chyby v logice aplikace, které nejsou snadno odhalitelné ani akceptačními testy a rychle nás informuje o chybách a nelogičnostech v uživatelském rozhraní. Skuteční uživatelé pak nebudou při pilotním provozu lacinými udivenými testovacími králíky. Bez automatických testů ale plýtváte časem těchto testerů-klikačů, protože živého člověka používáte jako robota bez mozku pro nalézání často triviálních a stále se vracejících chyb.

4. Nevěštěte termíny odstranění chyb!

Nedávejte žádné fixní odhady na odstranění chyb, ani nikoho z vývoje nevyčleňujte jen na odstraňování chyb. Vývojář není, a přes různé manažerské poučky ani nebude, anonymní zdroj, který sebereme z jiného projektu, posadíme k aplikaci, kterou nezná, ale u které dostane befelem, že za jednu normohodinu musí odstranit 20 bugů. Tato kouzla fungují jenom v Excelu. V reálném světě vývojář těch 20 bugů neodstraní, ani když ho posadíte do open space, který je oblepen motivačním majstrštykem vytisknutým z PowerPointu nejlepším absolventem MBA.

Pokud se objeví chyba, chopí se jí člověk, který za danou oblast odpovídá (konflikty přinejhorším vyřeší team leadeři). Vývojář neustále čte a refaktorizuje kód, pokud možno ihned také odstraňuje chyby . A jsme opět u testů – dokud ty automatizované testy nemáte, vývojáři do kódu raději nezasahují, protože nevědí, kde všude se změna projeví. Raději neriskují další možnou příčinu pádu aplikace po nasazení u zákazníka. A psát použitelné, ne jen formální-švejkovské testy, v nichž se hodnotí jen “code coverage“, se musí všichni vývojáři naučit. Počítejte s tím, že učení nějakou dobu zabere.

Mám zkušenost s 12 let starou aplikací psanou původně pro Visual Basic 6, poté částečně přepsanou na .Net Framework (Windows Forms, WPF, ASP.NET MVC klient), která byla po 9 letech postupně obalena testy. Ani dnes sice nejde o žádnou vývojářskou lahůdku, ale pracuje se na ní beze strachu, co při každé změně v aplikaci zničíme a za co nás bude zákazník křižovat v systému pro nahlášení chyb. Nic jiného než to, co píšu výše, se mi neosvědčilo.

Skutečně, nepatřím mezi lidi, co píšou testy, protože se to má nebo protože je to dneska příznakem dobrého vychování, hrdého agilního postoje k vývoji (ať už tahle floskule znamená cokoli) a všeobecně sdílené vysoké vývojářské kultury, ale proto, že se mi testy osvědčily. Ještě před tím, než se testování stalo módou, psal jsem si u každé aplikace jednoduché testovací skripty v konzoli. Tyto testovací skripty neměly pořádnou štábní kulturu, občas jsem testoval různé větve kódu tím, že jsem některé části skriptu zakomentoval, a byly to testy, které jsem na projektech pouštěl většinou jen já. Současné frameworky pro testování, jejich štábní kultura i “best practices” testování aplikací vám dovolují si tyhle podomácku zflikované (skoro)testy odpustit a rovnou začít čerpat ze zkušeností vývojářů, kteří si mnoha slepými uličkami testování již prošli. Proč toho nevyužít?

Mohl bych teď tady začít vypisovat, jaké jsou rozdíly mezi unit testy, integračními testy a akceptačnímí testy, na jaké typy aplikací se testy nejvíce hodí a kde jsou u některých aplikací patrné slabiny automatických testů, a poté se zaměřit na další podpůrné testovací nástroje, jakými jsou kromě mnoha dalších i knihovny pro generování Mock (Stub, Fake, Test double) objektů, ale to vše jsou spíše rozsáhlá témata vhodná pro rozpracování v další sérii článků, nikoli v článku motivačním, jakým je i tento.

Zde jsou další (nutné) bonbónky při vývoji aplikací, bez nároku na úplnost. Leitmotivem všech následujících bodů je snaha automatizovat na projektech vše, co se dá.

5. Verzování

Důležitý je i výběr vhodných nástrojů. Mezi nejdůležitější nástroje vývojáře podle mě patří slušný verzovací systém. Možná že dneska verzujete aplikace ještě tak, že jednou za čas, když je chuť, vhodná nebeská konstelace a vy nejste zrovna líní, zabalíte aktuální zdrojové kódy aplikace v raru nebo zipu. Možná vás překvapí, že tohle kupodivu není aplikace moudrého pravidla keep it simple and stupid (KISS) v celé jeho šíři, protože jste si z pravidla vytáhli a zdůraznili jen jeden, a to ne nejvhodnější, aspekt – stupid. Já bych vám doporučil, abyste neztráceli čas slučováním změn a řešením konfliktů ani v něčem tak zastaralém a nepohodlném jako je Subversion nebo dalších nástrojích téže generace. V Mercurialu (GITu a dalších distribuovaných verzovacích systémech) je třeba propagace změn z vývojové větve do hlavní (a zpět) otázka chvíle. V Subversion ani ve verzovacím systému TFS jsem po pár zkušenostech raději moc „branchů“ (větví) nedělal.

Zpočátku jsem nechápal, proč bych se měl vůbec o Mercurial zajímat. Byl to pro mě další verzovací nástroj, navíc v té době bez rozumné integrace s Visual studiem, které většinou při vývoji aplikací používám. Přesvědčilo mě nejprve to, že v Mercurialu nemusím být na cestách připojen stále přes internet/VPN, abych mohl „commitovat“ data. Do té doby jsem musel jet ve dvou režimech – doma nebo ve firmě dělám časté commity, na cestách se můj styl práce zcela mění a commity dělám až po delší době, abych nečekal na propagaci změn na server. V Mercurialu dělám lokální „commit“, kdy potřebuju, a pak jen přes příkaz “push” na dobrém připojení změny replikuju na server. Také jsem zjistil, že slučování změn a řešení konfliktů funguje nadmíru dobře, a dokonce i integrace s Visual studiem mi přestala chybět a raději používám příkazovou řádku. Samotného mě to překvapilo. Nemohl jsem si dovolit a stále nemohu rovnou zahodit verzovací systém TFS ani SVN, ale i pracovní adresáře těchto nástrojů si verzuju pomocí Mercurialu.

Poznámka: Sice vím, že při „kontinuální integraci“ bychom měli mít stále na paměti, že nevytváříme mnoho vedlejších větví kódu a všechny změny propagujeme hned do hlavní vývojové větve, ale znáte to určitě o té šedivé teorii a zeleném stromu hektického vývojářského života.

6. Build server

Automatické buildy aplikací spojené se spouštěním již napsaných testů. „Kontinuální integrace“ (Continuous integration) a „kontinuální –trvale udržitelné nasazení“ (Continuous delivery), na které narážím v dalším bodě, jsou pojmy, které se v poslední době často skloňují, a protože nemáme na jejich podrobné rozpracování prostor, dovolte, abych se vás zeptal: „Vy skutečně ještě nemáte svůj build server? A to přesto, že ho můžete často získat i zdarma a za vyzkoušení, jak určitě víte, nic nedáte?

7. Jednoduchý a dokumentovaný deploy

Mám na mysli automatické nasazení nové verze aplikace, aby testeři nemuseli pátrat, kde novou verzi seženou a aby nasazení do produkčního prostředí neznamenalo třídenní práci party lidí, kteří se metodou pokus-omyl snaží dostat aplikaci u zákazníka do použitelného stavu.

Nevíte, jak začít? Je váš proces nasazení aplikace příliš složitý? Já jsem u některých aplikací začínal tím, že jsem sepsal “průvodku verze”. V každé průvodce bylo napsáno, které knihovny a kam se mají nasadit, jaké sql skripty spustit, co změnit v konfiguračním souboru apod. Když jsem měl průvodku verze s algoritmem nasazení projektu, začal jsme postupně jednotlivé kroky algoritmu automatizovat.

8. Kontrola kódu

Alespoň u nováčků často kontrolujte kód, který píšou (code review), abyste rychle odstranili jejich špatné návyky. Vývojáři – nováčci by měli nejpozději po úvodním firemním drilu znát různé refaktorizační postupy a být si vědomi toho, že když program běží, nemusí to stačit, pokud kód ostatním vývojářům připomíná náhodný slepenec nečitelných příkazů a bláznem pojmenovaných proměnných.

9. Statická analýza kódu

Chcete dostat výjimku „očekáván objekt, ale hodnota je null“ při kontrole argumentů v metodě až za běhu aplikace, nebo byste raději byli upozorněni na problém s některými voláními metody ještě před nasazením aplikace? Nikdo soudný snad nemůže zvolit při takto sugestivní otázce špatnou odpověď. Statická analýza kódu dokáže odhalit některá problémová místa, která jsou pro kompilátor “košer”, a navíc vám dovolí třeba zkontrolovat, že všechny třídy v projektu obsahují konstruktor nutný pro deserializaci objektů. S jistou dávkou nepřesnosti bychom mohli říci, že statická analýza kódu může také sloužit jako částečná automatizace „code review“.

Závěrečná poznámka

Dovolím si jednu poznámku k „anonymní firmě“. Poznámka, jak čtenáři jistě poznají, je jen rezultátem předchozích bodů:

Zredukujte / vyhoďte všechny těžkotonážní, stále se objevující, neskutečně drahé, zákazníkům toho moc nepřinášející a pro vývojáře zabijácké nápady se zavedením nejhorší možné formy vodopádu – analýza->samostatný systémový design->vývoj->testy, v jehož bludném pádu se bude produkovat množství dokumentů rychlokvašenými analytiky / systémovými designery. Dokumentů v mizerné kvalitě a bez vazby na skutečné potřeby projektu. Analýza a systémový design jsou fáze projektu, které pomáhají jen do doby, než se jich chytí nějaký exot, který nikdy žádnou aplikaci nevyvíjel a který si myslí, že analytická práce spočívá ve štosování nahodilých myšlenek zákazníka do příslušné šablony pro use case. Což je dle mých zkušeností většina „čistých“ – míněno vývojem nedotčených – analytiků na pracovním trhu. 

Možná poznáte, jak chutná guláš, i když ho sami neumíte uvařit, ale jak vytvoříte zadání aplikace nebo časový harmonogram projektu, když jste nikdy žádnou aplikaci sami nevyvinuli?

Autor je vývojář, který nejčastěji píše v jazycích C# a C++, má zkušenost s vývojem desktopových, webových i mobilních aplikací a pořádá kurzy objektově orientovaného programování a návrhových vzorů.

Věděli jste, že nám můžete zasílat zprávičky? (Jen pro přihlášené.)

Komentáře: 32

Přehled komentářů

Michal Clanek roku
steinbauer René nezklamal
René stein Re: René nezklamal
patrik.sima Re: René nezklamal
Michal Zahradnicek Re: René nezklamal
Michal Re: René nezklamal
fos4 Build server
arron Re: Build server
vjur Re: Build server
Filda Re: Build server
Michal Re: Build server
xXx Přílepek
František Kučera Pár poznámek k poznámkám
René Stein Re: Pár poznámek k poznámkám
Heron Re: Pár poznámek k poznámkám
František Kučera Joelův test
Michal Augustýn Re: Joelův test
phi Re: Joelův test
backup problem je ve slove 'projekt'
Rene Stein Re: problem je ve slove 'projekt'
František Kučera Re: problem je ve slove 'projekt'
Rene Stein Re: problem je ve slove 'projekt'
František Kučera Re: problem je ve slove 'projekt'
Čelo Re: problem je ve slove 'projekt'
František Kučera Re: problem je ve slove 'projekt'
Čelo Re: problem je ve slove 'projekt'
František Kučera Re: problem je ve slove 'projekt'
Čelo Re: problem je ve slove 'projekt'
Franta Re: problem je ve slove 'projekt'
Jirka Re: problem je ve slove 'projekt'
Mennion Super článek
tuttle ufuf
Zdroj: https://www.zdrojak.cz/?p=3521