Software bez chyb – Test-Driven Development

V posledním článku jsme si řekli, proč vznikají chyby v softwarových produktech a čeho se vyvarovat, abyste mohli vydávat software bez chyb. Řekli jsme si, že odstranění chyb bude tím účinnější, čím blíže bude k tzv. bodu ovlivnění. Jednou z technik, které ovlivňují kód už při jeho vzniku je Test-Driven Development, neboli programování řízené testy.

Co je Test-Driven Development

Tento pojem je známý už více než dvě desítky let a předpokládám, že každý čtenář už o něm aspoň slyšel. Přesto ale raději zopakuji základní pojmy, protože kolem TDD panuje řada mýtů. Test-Driven Development probíhá krátkých cyklech, které mají tři fáze.

TDD cycle
  1. Fail – napište test, který neprojde (skončí s chybou)
  2. Pass – napište produkční kód, který způsobí, že test začne procházet
  3. Refactor – vylepšete strukturu kódu. Dbejte na to, aby po každé změně procházely všechny testy.

Fázím se někdy dávají různá jména, např. na obrázku používám Red-Green-Refactor, někdy se přidává čtvrtá fáze Think. Ale to není tak podstatné, podstatné je, že celý cyklus probíhá velmi rychle, maximálně za několik málo minut. V každé iteraci cyklu přidáme do produkčního kódu jednu malinkou věc navíc, typicky pouze jednotky řádků kódu.

Díky tomu, že nám neustále procházejí testy, máme plnou kontrolu nad změnami, které provádíme (pocit k nezaplacení).

Osobní poznámka na okraj: kdybych měl seřadit techniky, které jsem se za svůj profesionální život naučil jako programátor, TDD by bylo jednoznačně na prvním místě. Opravdu. Nepodceňujte to. Vypadá to jako drobná změna pracovních návyků, ale je to VELKÁ VĚC.

Jak TDD snižuje počet chyb

Dnešní článek je ale o tom, že Test-Driven Development pomáhá snižovat počet chyb. Například studie prováděná v roce 2008 na několika týmech v různých firmách dospěla k závěru, že použití TDD snižuje počet chyb před vydáním o 40 – 90%.

Proč to funguje? Napsal jsem to vlastně už na začátku – techniky pro prevenci chyb jsou tím účinnější, čím blíže bodu ovlivnění se nacházejí. No a TDD ovlivňuje kód přímo při jeho vzniku, patří tedy k nejúčinnějším technikám.

Jak to funguje? Tím, že napíšete nejdříve test a potom produkční kód, tak vlastně vyjádříte svůj záměr dvakrát – poprvé v testu a podruhé v kódu. Pravděpodobnost, že se spletete dvakrát, je velmi malá. Podobný princip používá například účetnictví – tam také musí být každá položka z jednoho účtu spárovaná s jinou položkou na jiném účtu, ale na opačné straně. Účetnictví tak umožňuje křížové kontroly.

Vedlejší efekty

Píšete-li dlouhodobě kód řízený testy, začnete si postupně všímat některých příjemných vedlejších efektů, které nejsou na první pohled zjevné. Pojďme si o nich postupně povědět:

  • Žádný strach. Kdysi dávno, když jsem ještě nepoužíval TDD, jsem věděl, že jsou některé části produktu, na které není radno sahat, zvláště pokud fungují. Prostě jsem byl rád, že fungují a držel jsem se od nich dál. S TDD tohle vymizí – žádná komponenta tak citlivá, aby se nedala ihned změnit. Vždyť přece máte testy a když napíšete něco, co bude mít nečekaný vliv na jinou část produktu, testy vás včas zastaví.
  • Krátké metody. Jelikož kód píšete postupně, kousek po kousku, vede vás to k psaní krátkých metod, které dělají jednu věc. Což je mimochodem vlastnost čistého kódu, o kterou byste se měli snažit stejně. S TDD ji máte zadarmo.
  • Příklady použití. Konec přemítání o tom, jak se vlastně metoda X používá. Mám testy a v nich si najdu ten, který metodu volá a tím pádem ukáže příklad použití.
  • Pokrytí. Na produktu, který vyvíjím zhruba 10 let pomocí TDD, jsem si nedávno poprvé pustil nástroj coverage, který měří pokrytí kódu. Výsledek? 91% pokrytí. Bez toho, že bych se o to snažil.
  • Testovatelnost. Každý, kdo si někdy zkusil napsat test na kód, který původně testovaný nebyl, ví, jaká je to dřina. Z podstaty věci se vám tohle při používání TDD nestane. Najednou máte testovatelné všechno. A většinou na několika úrovních. Takže když potřebujete něco změnit, je velmi jednoduché napsat další test.

Všechny tyto vedlejší efekty také nepřímo přispívají ke snížení množství chyb v software. Například, když píšete krátké metody, je jednodušší chybu izolovat a rychle ji opravit. Když existují příklady použití, můžete si být celkem jistí, že kódu dobře rozumíte, takže je menší šance, že v něm uděláte chybu. 

Co Test-Driven Development nezaručí

TDD vám pomůže zbavit se jednoho druhu chyb. Chyb, které vznikají z toho, že jako programátor nejste dokonalý a nezvládnete pochopit, co způsobí každá jednotlivá změna ve vašem kódu. Nezbaví vás ale chyb vyplývajících z toho, že jste špatně pochopili zadání nebo řešíte špatný problém.

Jinými slovy, TDD vám pomůže napsat kód správně (doing things right), ale nepomůže vám napsat správný kód (doing the right thing).

A TDD má samozřejmě i nevýhody – například je poměrně náročné na vnitřní disciplínu a minimálně na začátku vás trochu zpomalí. Je také poměrně obtížné se ho naučit. Ale to je téma na jiný článek. Z dnešního si můžete zapamatovat jedno: pokud chcete snížit množství chyb, které jako programátor produkujete, TDD je váš nejlepší přítel.

Pokud se vám článek líbil, sledujte mě na LinkedIn nebo Twitter.