Specification by Example - Gojko Adzic

Tuto knihu jsem si koupil na Eurostar konferenci, poté co se mi velmi líbila přednáška jejího autora – Gojko Adzice.

Když mi ji podepisoval napsal mi “Doufám, že ji shledáš inspirativní”. Určitě byla, a proto bych se chtěl s vámi podělit o hlavní myšlenky, které mne zaujaly a mohly by vás navnadit si ji přečíst celou, což bych určitě doporučil.

Tučné citace pochází přímo z knihy, kdežto české body pod nimi jsou myšlenky, které ve mně evokovaly.


"Building the product right and building the right product are two different things. We need to do both in order to to succeed."

•    Metodik, jak dělat software správně je celá řada, kdy z každé si musíme vybrat, to co považujeme za přínosné, přičemž musíme být velmi kritičtí, neboť co funguje jednomu, nemusí být dobré pro druhého.
•    Určitě bychom se ovšem měli vždy zamyslet, jestli vyvíjíme projekt, který někdo bude v reálu používat a přinese mu očekávanou hodnotu. Jinak řečeno, software může být vyvinut sledujíc sebelepší praktiky, ale pokud jej nikdo nebude používat, pouze jsme plýtvali časem, energií a penězi.


"Like a cheap wine, long paper documentation ages rapidly and leaves you with a bad headache if you try to use it a year after it was created."

•    Myslím, že tuto metaforu netřeba příliš komentovat. Všichni jsme se určitě setkali se sáhodlouhými dokumenty, které jsou těžko srozumitelné či použitelné už v době, kdy vznikly, natož o nějakou dobu později.


"The problem with any comprehensive documentation is, in fact, costly maintenance. Often, cost is the result of time spent on finding what needs to be changed."

•    Kocovina pocházející z obsáhlé a nestrukturované dokumentace má příčinu v její neudržitelnosti. Jedna, byť z business pohledu možná malá, změna vyžaduje změnu na mnoha místech dokumentace a často je těžké tato místa vůbec identifikovat. Mnohokrát jsem se setkal s nutností vyhledávání klíčových slov v celém dokumentu, což je ta nejzazší možnost.
•    Tento problém je podobný, jako když při vlastním psání kódu vývojář neuvažuje nad znovupoužitelností, dědičností atd. Nebo když se nám v automatických testech opakují stejné kroky v mnoha různých testech, nebo ještě hůře, je v každém z nich zautomatizována jiným způsobem. Tento problém vždy vyplave na povrch, někdy však příliš pozdě.


"Functional test automation is a good starting point to do something with documentation."

•    Pokud chceme zautomatizovat určitou funkci, musíme jí nejdříve dobře rozumět. Navíc chceme, aby byl test jasný, čitelný a udržitelný. Tyto požadavky nás nutí požadavky chápat a strukturovat.
•    Největší výhodu je, že výsledkem je "živá" dokumentace, která sama sebe jak definuje, tak verifikuje.


"Instance of focusing on a particular target process, decide to focus on improving product quality."

•    Možná se tento cíl jeví, jako mírné klišé, neboť ze všech stran slyšíme, že je třeba zlepšovat kvalitu, ale pokud celý tým tento cíl pochopí, a především si jej vezme za svůj, jistě už sám začne přicházet s vlastními návrhy na změny a bude prosazovat jejich realizaci.


"Agile software development methods are plagued with terminology and buzzwords... Explain Specification by Example as the process of gathering examples to clarify requirements, deriving tests, and automating them. Everything else will be left to discover."

•    V Agilním menifestu jsou shrnuty všechny podstatné body agilního vývoje. Myslím, že ne náhodu je tak stručný, nýbrž věřím, že je to jeho cílem. Zdá se mi, že slovo Agile se v poslední době používá snad až moc často a že začíná trpět podobnými nemocemi jako vodopád. Pro mne Agile znamená především svobodu, proces adaptace vlastní sady dobrých praktik (úmyslně nepoužívám slovo "nejlepší") a jejich neustálá evoluce.
•    Děsí mne když někdo říká, že jeho tým dělá např. Scrum (až na výjimky). Sledovat jednu metodologii může být nebezpečné, sledovat ji slepě dělá z myslících lidí ovce. Mějme přehled o více možnostech a vezměme si z každé, co se nám hodí, vždyť žádná z nich přeci neříká, tohle musíte dělat, ale spíše tohle děláme my a funguje nám to.


"Each change needs management support. If management responds wit pressure rather than support, people will fall back into their old ways of doing things and start protecting their position rather than collaborating."

•    Již jsem se setkal s přístupem, kdy se management bojí jakýkoliv změn, neboť nechce měnit jakžtakž fungující procesy. Často management také špatně reaguje na fakt, že každá změna v počátku vyžaduje určité úsilí a ovoce přináší až časem. Jak management získat na svou stranu, je vždy velmi individuální, ale já zastávám názor, že vždy pomáhá začít s vlastní iniciativou, vysvětlit a dokázat si racionálně obhájit vlastní názor, a také se vžít do role managementu.


"The biggest source of waste in software development is just-in-case code, it means software that was written without being needed."

•    Veškerá rozhodnutí by měla vždy mít dobrý důvod, to platí i o vývoji software. Pokud máme vyvíjet funkcionalitu, aniž víme k čemu bude sloužit, nebo ji zcela nerozumíme, je nejdříve nutné tyto nejasnosti odstranit. Vývoj na základně hádání je cesta do pekel, sice se zdá rychlejší, ale vede špatným směrem.
•    Často jsem se setkal s povzdechem, že to prostě nejde jinak, že jsou termíny atd. Dobrá tedy, potom doporučuji aspoň zpětně měřit, jak či zda vůbec, bude daná funkcionalita opravdu využívaná, kolikrát bude muset být přepracována, případně kolik chyb v ní bude. Takovýto výstup pak může být dobrým argumentem pro změnu.


"Specifying collaboratively is a great way to build a shared understanding of what needs to be done. Collaboration also helps teams produce specifications that are easy to understand and tests are easy to maintain."

•    V případě, že je specifikace vytvářená pouze jedním člověk (rolí) je vždy velmi subjektivní, neboť každý z nás se na věc dívá z jiného úhlu a jiným pohledem. Všichni známe lidovou moudrost - víc hlav, víc ví.
•    Pokud se na specifikaci požadavků podílí všechny role a stakeholdeři, výrazně tím snižujeme riziko, že něco bude opomenuto, nebo pochopeno jinak. Stakeholder má většinou pouze základní představu toho, co by chtěl. Ta je formována primárně analytikem, který úzce spolupracuje s developrem, čímž je zaručena implementovatelnost, a s testerem (QA), což zaručuje testovatelnost a udržitelnost. Pouze všichni dohromady jsou schopni vytvořit specifikaci, která bude reálným (živým) obrazem cílového produktu. Pokud se jedna z těchto rolí nebude specifikace účastnit, nikdy nemůžeme této reálnosti (živosti) dosáhnout.
•    V případě, že je organizačně nemožné uspořádat větší meetingy, měl by se na analýze každého problému účastnit vždy alespoň jeden analytik, developr a tester (Three amigos)


“Examples should be precise and testable.”

•    Každý příklad musí být vždy jednoznačný, musí být jasné jeho hranice a měl by, pokud možno, specifikovat pouze jednu funkci či požadavek. V případě, že chceme popsat rozsáhlejší funkcionalitu, vždy bychom se měli zamyslet nad tím, zda není vhodnější celek dekomponovat.
•    Příklad by měl mít jasné vstupy a výstupy. Proces dosažení výsledku by měl být popsán přirozenou a srozumitelnou formou. Často jsem se setkal s tím, že ve snaze o stručnost utrpěla právě smysluplnost a čitelnost, nebo, že specifikace byla spíše podobna skriptu.


“Scripts are not specifications. Business users will often think about performing an action through the user interface or through several steps, explaining how they use the system to achieve something instead of what the system is supposed to do. Such examples are scripts, not specifications.
Specifications should be about business functionality, not software design.”

•    Skript, chápejme jako posloupnost kroků k dosažení určitého cíle, má již podstatně nižší úroveň abstrakce než příklad. V některých situacích může pomoci objasnit požadovanou funkcionalitu, ale vždy bychom ke konkrétním skriptům měli přistupovat jako k doplňující informaci, nikoli jako k příkladu. V opačném případě se může lehce stát, že zabijeme tvůrčího ducha zbytečným množstvím detailů, které můžeme vyspecifikovat později, nebo je nechat na kreativitě vlastních vývojařů, kteří to jistě ocení.


“What should it do? How should it work?”

•    Dva úhly pohledu, či chcete-li dvě úrovně abstrakce. Který je rozšířenější? Bohužel mnohem častěji se setkáváme s otázkou po tom, jak má co pracovat, přičemž první otázka, která zjišťuje vlastní podstatu je opomíjena. V mnoho případech na ni dojde až později, což většinou vede k nutnosti přepracování. Budeme-li se nejdříve ptát po podstatě a až potom (nebo vůbec) po způsobu jejího dosažení, předejdeme mnohým komplikacím.
•    Rozdíl mezi těmito dvěma pohledy je také nutné vysvětlit zákazníkům, neboť právě oni jsou často přesvědčeni, že ví, co chtějí a proto spíše specifikují, jak toho dosáhnout. Proto bývají velmi často zaskočeni otázkou "Proč?".


“Do not get trapped in user interface details.”

•    Specifikace budoucího UI je činnost, která zabíjí nejvíce nápadů. Lidský mozek dokáže nejlépe pracovat s obrazy, právě proto je zrak našim nejdůležitějším smyslem. Ovšem návrh UI snižuje abstrakci na nejnižší úroveň, proto se mu pokusme, především při sběru požadavků, co nejvíce vyhnout.


“Do not try to cover every single case.”

•    Zaměřme se vždy nejdříve na klíčové příklady, ostatní mohou být přidány později, či mohou (pokud je to nutné) zůstat pouze v testech. V opačném případě se dokumentace stane nepřehlednou a stakeholdeři ztratí zájem s ní pracovat.
•    Happy path je přímá cesta k dosažení cíle. Právě tyto cesty by měly být součástí specifikace. Ostatní možnosti, či hranice mohou být objeveny později, či mohou být zachyceny komplexně.


“Specifications should be in domain language.”

•    Jestliže je jednoznačnost jedním z nejdůležitějších atributů dobré specifikace, je podstatné používat jednoznačný jazyk. Specifikace by rovněž měla být co nejpřirozenější. Východiskem z těchto dvou zdánlivě protichůdných pólů je stanovení společného slovníku pojmů. Tento slovník by měl definovat pojmy, které jsou klíčové pro danou doménu a jejich závislosti.
•    Snažme se omezit použití příslovcí, které jsou vždy nejednoznačné. Slovesa a podstatná jména mají mnohem větší popisnost.


“The automation code depends on the specifications but not the other way around.”

•    Automatické testy validují specifikaci. V případě, že je nutné změnit specifikaci v momentě, kdy ji chceme automatizovat, je čas se zamyslet. Problém bývá nejčastěji v samotné specifikaci, respektive v její netestovatelnosti. V prvním případě je třeba nejdříve opravit specifikaci. Nikdy se nepouštějme do automatizace "špatné" specifikace, jinak docílíme neudržitelných a nepoužitelných testů. Automatizovaný chaos je jen rychlejší chaos.
•    Když neprojde automatický test důsledkem chyby v aplikaci (kódu), jedná se o dobrý test, o dobrý test se nejedná pokud je sám důvodem proč neuspěl, pak jej musíme opravit.


“Automation is also very important long term because it enables us to check more cases more frequently.”

•    Automatizace má vždy vlastní režii, jejíž návratnost záleží na délce projektu a jejím využití. ROI je přímo úměrný tomu, jako často jsou automatické testy spouštěny, to znamená jaký je ušetřený ekvivalent manuálního funkčního testování (EMTE).
•    Vlastní vývoj automatických testů je většinou jednorázová investice, kdežto jejich údržba bývá největší výzvou. Proto je důležité, abychom s údržnou a znovupoužitelností počítali již na začátku. Právě zde naráží automatizace přístupem Nahraj a Pusť.
•    Automatizace má největší ROI při regresi, tedy ověření, že stávající funkcionalita stále dělá co má a že nebyla rozbita při vývoji nové.
•    Při kontinuální integraci, nejlépe s funkčními nočním buildy, se dostáváme do zelených čísle velmi brzy, navíc tím uvolníme testery pro exploratory testování a jiné prospěšné aktivity.


“Do not postpone or delegate automation.”

•    Automatizaci není vhodné odkládat na někdy, až na ni bude čas. Důvody pro to jsou především dva. První je vlastní ROI, kdy návratnost stoupá s počtem reálných spuštění testu, to znamená kolik času jsem ušetřili tím, že jsme daný test automatizovali a nemuseli jsme jej provést manuálně. Druhým, neméně důležitým aspektem, je to, že právě automatizace může odhalit nekonzistentnost specifikace. Automatizace přináší další pohled na požadavky. Proto je TDD tak doporučovaným přístupem a přináší okamžitou odezvu a jistotu.


“Avoid automating existing manual test scripts.”

•    Automatizace manuálních testů způsobem jedna ku jedné může vést k mnoha problémům. Nejčastějším je to, že vznikne ohromné množství automatických testů, které testují střípky aplikace. Automatické testy by se měly zaměřit primárně na kompletní scénáře. Navíc automatizace by měla efektivně řešit přípravu dat a všech ostatních předpokladů, které jsou v případě manuálních testů často rovněž jejich součástí.
•    Automatizace samozřejmě z manuálních testů vychází, testuje přeci stejný systém, ale jiným, vývoji bližším, způsobem. Proto je často nutné, aby automátor měl alespoň základní znalosti programování.
•    Důležité je najít poměr mezi automatickými testy z pohledu UI a API. Testy, které využívají UI jsou většinou nejpomalejší a nejnákladnější na vývoj i údržbu. Proto bychom se měli držet toho, že co lze automatizovat bez UI, bez něj automatizujme, a využívejme UI testy především k testování kompletních scénářů z pohledu uživatele (akceptační testy).


“With automated testing, people spend the most time trying to understand what is wrong when a test fails.”

•    Jakmile je automatický test napsán, nevyžaduje další investice vyjma údržby. Avšak v momentě, kdy test neprojde, je nutné analyzovat důvod proč. Právě tato analýza pádů je potenciálním "žroutem" času, který je specifický právě pro automatické testy. V případě manuálního testování se s tímto problémem nesetkáme, protože vždy známe kontext, kdy k chybě došlo. A právě tento kontext je klíčový i pro automatizaci. Log by měl poskytovat srozumitelným způsobem všechny informace, které jsou potřebné k reprodukování chyby. Jinak se jakýkoli test, který neprojde, stává noční můrou.


“Choose what to automate.”

•    Nikdy není vhodné automatizovat vše, neboť některé testy jsou mnohem účinější a efektivnější manuálně. Typickými příklady jsou ty, které testují vlastní UI. Pokud test vyžaduje "subjektivitu" je vždy na zvážení, zda jej vůbec automatizovat. Dalším důvodem, proč daný test ponechat manuálním je jednoduše malá návratnost takovéto investice.


“Move abstraction of test scripts to higher level. If you have a small expression that has a meaning, refactor it to a method and give it a name.”

•    Vlastní test je většinou kompozice opakujících se business akcí. Proto je vhodné tyto akce automatizovat zvláště a propagovat je. Tím dosáhneme toho, že jestliže se vlastní implementace takovéto akce změní, tato změna vyžaduje update pouze na jednom místě, nikoli v každém z testů, kde je použita.


Tímto končí první záznam v mém profesním „čtenářském deníku“. Pokud byste ocenili podobné výpisky z dalších knih, které mám na seznamu k přečtení, dejte mi vědět. Pokud si naopak myslíte, že je to zbytečné, budu rád, když se o to se mnou rovněž podělíte.