it-swarm-eu.dev

Co byste měli testovat jednotkovými testy?

Jsem čerstvě mimo školu a příští týden budu univerzitu někde. Viděli jsme jednotkové testy, ale příliš jsme je nepoužívali; a všichni o nich mluví, takže jsem si myslel, že bych měl nějaké udělat.

Problém je, že nevím co otestovat. Mám otestovat běžný případ? Případ Edge? Jak zjistím, že funkce je dostatečně pokryta?

Vždycky mám strašný pocit, že zatímco test prokáže, že funkce funguje v určitém případě, je naprosto zbytečné dokazovat, že funkce funguje, období.

128
zneak

Moje osobní filozofie byla dosud:

  1. Otestujte společný případ všeho, co můžete. To vám řekne, kdy se tento kód přestane po provedení nějaké změny (což je podle mého názoru největší výhoda automatizovaného testování jednotek).
  2. Otestujte případy Edge několika neobvykle složitých kódů, o kterých si myslíte, že pravděpodobně budou mít chyby.
  3. Kdykoli najdete chybu, napište před jejím opravením testovací případ
  4. Kdykoli má někdo čas zabít, přidejte testy Edge-case do méně kritického kódu.
124
Fishtoaster

Spousta odpovědí, které se dosud nikdo nedotkl rozdělení ekvivalence a analýza hraniční hodnoty , zásadní úvahy v odpovědi na danou otázku. Všechny ostatní odpovědi, i když užitečné, jsou kvalitativní, ale je možné - a raději - být kvantitativní. @fishtoaster poskytuje několik konkrétních pokynů, jen pokukování pod kryty kvantifikace testu, ale rozdělení podle ekvivalence a analýza hraničních hodnot nám umožňují dělat lépe.

V rozdělení podle ekvivalence rozdělte sadu všech možných vstupů do skupin na základě očekávaných výsledků. Jakýkoli vstup z jedné skupiny poskytne ekvivalentní výsledky, takže se takové skupiny nazývají třídy ekvivalence. (Všimněte si, že ekvivalentní výsledky znamenají ne stejné výsledky.)

Jako jednoduchý příklad zvažte program, který by měl transformovat malá písmena ASCII znaky na velká písmena. Ostatní znaky by měly podstoupit transformaci identity, tj. Zůstat nezměněny. Zde je možné rozdělení do tříd ekvivalence:

| # |  Equivalence class    | Input        | Output       | # test cases |
+------------------------------------------------------------------------+
| 1 | Lowercase letter      | a - z        | A - Z        | 26           |
| 2 | Uppercase letter      | A - Z        | A - Z        | 26           |
| 3 | Non-alphabetic chars  | [email protected]#,/"... | [email protected]#,/"... | 42           |
| 4 | Non-printable chars   | ^C,^S,TAB... | ^C,^S,TAB... | 34           |

V posledním sloupci je uveden počet testovacích případů, pokud je všechny vyjmenujete. Technicky by podle pravidla @ fishtoaster 1 zahrnovalo 52 testovacích případů - všechny z prvních dvou řádků uvedených výše spadají do „společného případu“. @ Fishtoaster's Rule 2 by přidal také některé nebo všechny z řádků 3 a 4 výše. Ale při testování rozdělení na ekvivalenci postačí jakýkoli jeden testovací případ v každé třídě ekvivalence. Pokud zvolíte „a“ nebo „g“ nebo „w“, testujete stejnou cestu k kódu. Máte tedy celkem 4 testovací případy namísto 52+.

Analýza hraničních hodnot doporučuje mírné upřesnění: v podstatě to naznačuje, že ne každý člen třídy ekvivalence je, dobře, ekvivalentní. To znamená, že hodnoty na hranicích by také měly být považovány za hodné testovacího případu samy o sobě. (Jedním jednoduchým zdůvodněním je nechvalně známá chyba jedna po druhé !) Pro každou třídu ekvivalence byste tedy mohli mít 3 testovací vstupy. Při pohledu na vstupní doménu výše - as určitými znalostmi ASCII hodnot) - možná přijdu s těmito vstupy do testovacího případu:

| # | Input                | # test cases |
| 1 | a, w, z              | 3            |
| 2 | A, E, Z              | 3            |
| 3 | 0, 5, 9, !, @, *, ~  | 7            |
| 4 | nul, esc, space, del | 4            |

(Jakmile získáte více než 3 mezní hodnoty, které naznačují, že budete chtít přehodnotit své původní vymezení třídy ekvivalence, bylo to natolik jednoduché, že jsem se nevrátil, abych je upravil.) Analýza hraničních hodnot nás tedy přivedla k 17 testovacích případů - s vysokou jistotou úplného pokrytí - ve srovnání se 128 testovacími případy, aby bylo provedeno vyčerpávající testování. (Nemluvě o tom, že kombinatorika diktuje, že vyčerpávající testování je jednoduše nemožné pro jakoukoli aplikaci v reálném světě!)

68
Michael Sorens

Pravděpodobně můj názor není příliš populární. Ale navrhuji, abyste byli ekonomičtí s jednotkovými testy. Pokud máte příliš mnoho jednotkových testů, můžete snadno strávit polovinu času nebo více udržováním testů namísto skutečného kódování.

Navrhuji, abyste psali testy na věci, které ve vašem střevě mají špatný pocit, nebo na věci, které jsou velmi důležité a/nebo elementární. Testy jednotek IMHO nenahrazují dobré technické a obranné kódování. V současné době pracuji na projektu, který je víceméně nepoužitelný. Je to opravdu stabilní, ale bolest na refaktora. Ve skutečnosti se nikdo nedotkl tohoto kódu za jeden rok a softwarový balík, na kterém je založen, je 4 roky starý. Proč? Protože je to zaplněno jednotkovými testy, přesněji: testy jednotek a automatizované integrační testy. (Už jste někdy slyšeli o okurce a podobně?) A tady je to nejlepší: Tento (dosud) nepoužitelný kus softwaru byl vyvinut společností, jejíž zaměstnanci jsou průkopníky v testovací vývojové scéně. : D

Můj návrh je tedy:

  • Začněte psát testy po vyvinuli jste základní kostru, jinak by refaktoring mohl být bolestivý. Jako vývojář, který se vyvíjí pro ostatní, nikdy nedostanete požadavky hned na začátku.

  • Ujistěte se, že vaše testy jednotek mohou být provedeny rychle. Pokud máte integrační testy (jako je okurka), je to v pořádku, pokud to trvá trochu déle. Ale dlouhodobé testy nejsou zábavné, věřte mi. (Lidé zapomínají na všechny důvody, proč se C++ stala méně populární ...)

  • Nechte tyto věci TDD odborníkům na TDD.

  • A ano, někdy se soustředíte na případy Edge, někdy na běžné případy, podle toho, kde očekáváte neočekávané. I když vždy očekáváte neočekávané, měli byste opravdu přehodnotit pracovní postup a disciplínu. ;-)

20
Philip

Pokud nejprve testujete s vývojem řízeným vývojem, vaše pokrytí se bude pohybovat v rozmezí 90% nebo vyšším, protože nebudete přidávat funkčnost, aniž byste pro něj nejprve napsali test vadné jednotky.

Pokud přidáváte testy po skutečnosti, pak nemohu dostatečně doporučit, abyste dostali kopii Efektivně pracuje se starým kódem od Michael Feathers a podívejte se na některé z techniky pro přidání testů do kódu a způsoby refaktoringu kódu, aby byl testovatelnější.

8
Paddyslacker

Pokud začnete postupovat podle metod Test Driven Development , budou vás třídit průvodcem , kteří vás provedou procesem, a budou vědět, co testovat, přijde přirozeně. Některá místa, kde začít:

Testy jsou na prvním místě

Nikdy nikdy nepište kód před napsáním testů. Vysvětlení viz Red-Green-Refactor-Repeat .

Zápis regresních testů

Kdykoli narazíte na chybu, napište testcase a ujistěte se, že selže . Pokud nemůžete reprodukovat chybu skrze selhávající testcase, opravdu jste to nenašli.

Opakování červeno-zelené-opakování

Červená : Začněte psáním nejzákladnějšího testu chování, které se pokoušíte implementovat. Přemýšlejte o tomto kroku jako o psaní příkladového kódu, který používá třídu nebo funkci, na které pracujete. Ujistěte se, že kompiluje/nemá syntaktické chyby a že selže . To by mělo být zřejmé: nenapsali jste žádný kód, takže musí selhat, že? Důležité je naučit se zde, že pokud neuvidíte test selhání alespoň jednou, nikdy si nemůžete být jisti, že pokud projde, udělá to kvůli něčemu, co jste udělali kvůli nějakému falešnému důvodu.

Zelená : Napište nejjednodušší a nejhloupější kód, který ve skutečnosti umožňuje testovací test. Nesnažte se být chytří. I když vidíte, že existuje zjevný případ Edge, ale test bere v úvahu, nezapisujte kód, který by to zvládl (ale nezapomeňte na případ Edge: Budu to potřebovat později). Myšlenka je, že každý kus kódu, který píšete, každý if, každý try: ... except: ... by mělo být odůvodněno testovacím případem. Kód nemusí být elegantní, rychlý nebo optimalizovaný. Jenom chcete, aby test prošel.

Refaktor : Vyčištění kódu, správné názvy metod. Zjistěte, zda test stále probíhá. Optimalizovat. Proveďte test znovu.

Opakovat : Pamatujete si případ Edge, který test nepokryl, že? Teď je to jeho velký okamžik. Napište testcase, který pokrývá tuto situaci, sledujte, jak to selže, napište nějaký kód, podívejte se na pass, refactor.

Otestujte váš kód

Pracujete na nějakém konkrétním kódu, a to je přesně to, co chcete vyzkoušet. To znamená, že byste neměli testovat funkce knihovny, standardní knihovnu ani kompilátor. Pokuste se také vyhnout testování „světa“. To zahrnuje: volání externích webových rozhraní API, některých věcí náročných na databázi atd. Kdykoli se můžete pokusit zesměšnit (vytvořte objekt, který sleduje stejné rozhraní, ale vrací statická, předdefinovaná data).

6
Ryszard Szopa

U jednotkových testů začněte testováním, zda provádí to, co je navrženo. To by měl být úplně první případ, který píšete. Pokud je součástí návrhu „měla by být vyvolána výjimka, pokud projdete nevyžádanou poštou“, otestujte to také, protože to je součástí návrhu.

Začněte tím. Jakmile získáte zkušenost s tím nejzákladnějším testováním, začnete se učit, zda je to dostačující, a začnete vidět další aspekty vašeho kódu, které vyžadují testování.

3
Bryan Oakley

Skladová odpověď je "vyzkoušejte vše, co by se mohlo zlomit" .

Co je příliš snadné rozbít? Datová pole, přístup k majetku mrtvého v mozku a podobná režijní plocha. Něco jiného pravděpodobně implementuje určitou identifikovatelnou část požadavku a může být přínosem z testování.

Vaše ujeté kilometry - a postupy vašeho pracovního prostředí - se samozřejmě mohou lišit.

0
Jeffrey Hantin