it-swarm-eu.dev

Kdy je vhodné testovat jednotku?

Pracuji v malé společnosti jako sólový vývojář. Ve skutečnosti jsem jediným vývojářem ve společnosti. Mám několik (relativně) velkých projektů, které jsem pravidelně psal a udržoval, a žádný z nich nemá testy na jejich podporu. Při zahájení nových projektů se často ptám, zda bych měl vyzkoušet přístup TDD. Zní to jako dobrý nápad, ale upřímně nemohu nikdy odůvodnit další práci.

Ve svém návrhu tvrdě pracuji na tom, abych myslel dopředu. Uvědomuji si, že jednoho dne bude muset jiný vývojář kód udržovat, nebo ho alespoň vyřešit. Udržuji věci co nejjednodušší a komentuji a dokumentuji věci, které by bylo obtížné pochopit. Faktem je, že tyto projekty nejsou tak velké nebo složité, že by je slušný vývojář chtěl pochopit.

Mnoho příkladů, které jsem viděl při testech, se dostalo až k markantům, pokrývajících všechny aspekty kódu. Protože jsem jediným vývojářem a jsem velmi blízko kódu v celém projektu, je mnohem efektivnější řídit se testovací metodou zápis-pak-ručně-test. Také jsem zjistil, že požadavky a funkce se mění dostatečně často, aby udržovací testy přidaly značné množství přetažení na projektu. Čas, který by jinak mohl být stráven řešením obchodních potřeb.

Takže jsem vždy skončil se stejným závěrem. Návratnost investic je příliš nízká.

Mám příležitostně nastavit několik testů, abych se ujistil, že jsem napsal algoritmus správně, jako je výpočet počtu let, kdy byl někdo ve společnosti na základě data pronájmu. Ale z hlediska pokrytí kódu jsem pokrýval asi 1% mého kódu.

V mé situaci byste stále našli způsob, jak zajistit pravidelné testování jednotek, nebo jsem oprávněný vyhnout se této režii?

PDATE: Několik věcí o mé situaci, které jsem vynechal: Moje projekty jsou všechny webové aplikace. Abych pokryl celý můj kód, musel bych použít automatické testy uživatelského rozhraní, a to je oblast, kde stále nevidím velký přínos oproti ručnímu testování.

143
Ken Pespisa

Mnoho příkladů, které jsem viděl při testech, se dostalo až k markantům, pokrývajících všechny aspekty kódu.

Tak? Nemusíte testovat všechno. Jen relevantní věci.

Protože jsem jediným vývojářem a jsem velmi blízko kódu v celém projektu, je mnohem efektivnější řídit se testovací metodou zápis-pak-ručně-test.

To je vlastně nepravda. Není to efektivnější. Je to opravdu jen zvyk.

To, co dělají další jednotliví vývojáři, je napsat náčrt nebo obrys, napsat testovací případy a poté vyplnit obrys konečným kódem.

To je velmi, velmi efektivní.

Také jsem zjistil, že požadavky a funkce se mění dostatečně často, aby udržovací testy přidaly značné množství přetažení na projektu.

To je také nepravdivé. Testy nejsou tažením. Změny požadavků jsou tažením.

Musíte opravit testy, aby odrážely požadavky. Ať už jejich markanty, nebo na vysoké úrovni; Napsáno první nebo Naposledy napsané.

Kód není proveden, dokud testy neprojdou. To je jedna univerzální pravda o softwaru.

Můžete mít omezený akceptační test „tady to je“.

Nebo můžete provést nějaké testy jednotek.

Nebo můžete mít obojí.

Ale bez ohledu na to, co děláte, vždy existuje test, který prokáže, že software funguje.

Navrhoval bych, že díky trochu formalitě a sadě nástrojů pro testování jednotek je tento test mnohem užitečnější.

85
S.Lott

Představte si, že jste měli sadu testů, které by mohly běžet v oční linky a rozsvítily by zelené nebo červené světlo. Představte si, že tato sada testů testována všechno! Představte si, že jediné, co musíte udělat, abyste spustili sadu testů, bylo napsat ^ T. Jakou moc vám to dá?

Mohli byste změnit kód beze strachu, že něco porušíte? Mohli byste přidat novou funkci, aniž byste se obávali porušení staré funkce? Dokážete rychle vyčistit chaotický kód bez obav z poškození?

Ano, můžete dělat všechny ty věci! A co by se s vaším kódem stalo v průběhu času? Čistší a čistší by bylo, protože by nehrozilo žádné čištění.

Představme si, že jste měl na rameni trochu víly. Pokaždé, když napíšete řádek kódu, víla přidá něco do testovací sady, která otestovala, že ten řádek kódu udělal to, co měl dělat. Takže každých pár sekund můžete stisknout ^ T a uvidíte, že poslední řádek kódu, který jste napsali, fungoval.

Kolik ladění si myslíte, že byste udělali?

Pokud to zní jako fantazie, máte pravdu. Realita se ale příliš neliší. Vyměňte oční link za pár vteřin a vílu disciplínou TDD, a vy jste to docela dostali.

Řekněme, že se vracíte k systému, který jste vytvořili před rokem, a zapomněli jste, jak vytvořit jeden z centrálních objektů. Existují testy, které tento objekt vytvářejí všude, kde je možné jej vytvořit. Můžete si přečíst tyto testy a zablokovat paměť. Potřebujete zavolat API? Existují testy, které volají API vždy, když jej lze nazvat. Tyto testy jsou malé dokumenty, psané v jazyce, kterému rozumíte. Jsou naprosto jednoznačné. Jsou tak formální, že vykonávají. A nemohou se zbavit synchronizace s aplikací!

Nestojí to za investici? Musíš si dělat srandu! Jak by mohl někdo chtít tuto sadu testů? Udělejte si laskavost a přestaňte se hádat o hlouposti. Naučte se dělat TDD dobře a sledujte, jak rychlejší postupujete a jak čistší je váš kód.

113
Uncle Bob.

Chyba, kterou děláte, je, že vidíte testování jako časovou investici bez okamžité návratnosti. Nemusí to nutně fungovat.

Nejprve píšete testy opravd se zaměřuje na to, co musí tato část kódu udělat.

Za druhé jejich odhalení odhaluje chyby, které by jinak při testování vyšly.

Třetí spuštění je někdy ukazuje chyby, které by jinak při testování nedocházelo a pak by vás opravdu kouslo do zadku ve výrobě.

Začtvrté, pokud narazíte na chybu se spuštěným systémem a vytvoříte pro ni test jednotky, nebudete ji moci znovu představit. To může být opravdu velká pomoc. Znovu zavedené chyby jsou běžné a velmi nepříjemné.

Za páté, pokud někdy potřebujete předat kód někomu jinému, zkušební sada usnadní jejich život mnohem jednodušší. Také, pokud jste ignorovali projekt a vrátili se k němu po několika letech, nebudete už k němu tak blízko a bude vám také užitečný.

Moje zkušenost je taková, že v průběhu vývoje projektu, díky důkladným testům jednotek, byl tento proces vždy rychlejší a spolehlivější.

34
glenatron

Kluci v JUnit (Java Unit test framework) mají filozofii, která , pokud je testování příliš jednoduché, netestujte . Velmi doporučuji přečíst jejich FAQ o nejlepších postupech , protože je to docela pragmatické.

TDD je jiný proces psaní vašeho softwaru. Základním předpokladem testování jednotky je to, že budete trávit méně času debuggerem při procházení kódem a rychleji zjistíte, že pokud váš kód náhodně poruší něco jiného v systému. To se hodí k TDD. Cyklus TDD je následující:

  1. Napište test
  2. Sledujte, jak to selže (dokažte, že máte co dělat)
  3. Napište jen to, co je potřeba k úspěšnému provedení testu - nic víc.
  4. Sledujte, jak to projde (yay!)
  5. Refaktor (vylepšit)
  6. Omyjte, opláchněte a opakujte

Co je méně zřejmé při použití TDD je to, že mění způsob psaní vašeho kódu . Vynucením přemýšlení o tom, jak otestovat/ověřit, že kód funguje, píšete testovatelný kód. A protože mluvíme o testování jednotek, obvykle to znamená, že váš kód bude modulárnější. Modulární a testovatelný kód je pro mě velká výhra vpředu.

Nyní musíte testovat věci jako vlastnosti C #? Představte si vlastnost definovanou takto:

bool IsWorthTesting {get; set;}

Odpověď by byla „ne“, nestojí to za testování, protože v tuto chvíli testujete jazykovou funkci. Jen věřte, že to kluci z platformy C # měli pravdu. Kromě toho, pokud by selhalo, co byste mohli opravit?

Také zjistíte, že existují určité části vašeho kódu, které velmi dobře budou příliš velké úsilí na správné testování. To znamená, že to nedělejte, ale ujistěte se, že vyzkoušíte kód, který používá/je používán problémovým problémem:

  • Kontrolované výjimky, ke kterým může dojít pouze v případě, že instalace selhala. Java jich má spoustu. Je třeba napsat blok úlovku nebo deklarovat zaškrtnutou výjimku, i když neexistuje způsob, jak může selhat bez hackování nainstalovaných souborů.
  • Uživatelská rozhraní. Nalezení testované kontroly a vyvolání správných událostí pro simulaci akcí uživatele jsou velmi problematické a v některých případech nemožné. Pokud však používáte model Model/Pohled/Řadič, můžete se ujistit, že váš model a řadiče jsou testovány, a nechat část pohledu na ruční testování.
  • Interakce mezi klientem a serverem. Toto již není jednotkový test a nyní jde o integrační test. Zapište všechny části, které vedou k odesílání a přijímání zpráv, přes drát, ale ve skutečnosti nepřekračujte drát. Dobrým přístupem je snížit odpovědnost kódu, který ve skutečnosti mluví po dráze, se surovou komunikací. V testovacím kódu jednotky zesměšňujte komunikační objekt, abyste se ujistili, že se služby chovají podle očekávání.

Věřte tomu nebo ne, TDD vám pomůže upadnout do udržitelného tempa rozvoje. Není to kvůli magii, ale spíše proto, že máte pevnou smyčku zpětné vazby a jste schopni rychle zachytit opravdu němé chyby. Náklady na opravu těchto chyb jsou v podstatě konstantní (přinejmenším dostačující pro účely plánování), protože malé chyby nikdy nevyrostou jako velké chyby. Porovnejte to s prasklou povahou kódového nárazu/ladění sprintu.

33
Berin Loritsch

Musíte vyvážit náklady na testování a náklady na chyby.

Zápis testu 10 řádkových jednotek pro funkci, která otevře soubor, kde selhání je „soubor nenalezen“, je zbytečné.

Funkce, která dělá něco složitého ke složité datové struktuře - pak samozřejmě ano.

Choulostivý kousek je mezi tím. Ale nezapomeňte, že skutečná hodnota jednotkových testů netestuje konkrétní funkci, ale testuje složité interakce mezi nimi. Takže test jednotky, který zjistí, že změna v jednom kousku kódu, přeruší nějakou funkci v jiném modulu ve vzdálenosti 1000 řádků, stojí za jeho váhu v kávě.

24
Martin Beckett

Testování je hazard.

Vytvoření testu je sázka, že náklady na chyby v jednotce, které se vyskytnou, a nezachytily je tímto testem (nyní a během všech budoucích revizí kódu), jsou vyšší než náklady na vývoj testu. Tyto náklady na vývoj testů zahrnují věci, jako je výplatní listina za přidané testovací inženýrství, přidaná doba uvedení na trh, náklady na ztracené příležitosti z nekódování jiných věcí atd.

Jako každá sázka, někdy vyhrajete, někdy prohrajete.

Někdy zpožděný software s mnohem menším počtem chyb vyhrává rychlými, ale chybnými věcmi, které se dostanou na trh jako první. Někdy opak. Musíte se podívat na statistiku ve svém konkrétním oboru a na to, jak moc vedení chce hrát.

Je nepravděpodobné, že by některé typy chyb byly provedeny nebo aby byly vyřazeny z jakýchkoli časných testů zdravého rozumu, protože statisticky nestojí čas na vytvoření dalších specifických testů. Ale někdy jsou náklady na bug tak velké (lékařské, jaderné atd.), Že společnost musí vzít prohrávající sázku (podobně jako pojištění nákupu). Mnoho aplikací nemá tak vysoké náklady na selhání, a proto nepotřebují vyšší neekonomické pojistné krytí. Ostatní ano.

23
hotpaw2

Moje rada je pouze otestovat kód, který chcete správně fungovat.

Netestujte kód, který chcete být buggy, a způsobit vám problémy po silnici.

11
Nick Hodges

Často se ptám, jestli bych měl vyzkoušet přístup TDD. Zní to jako dobrý nápad, ale upřímně nemohu nikdy odůvodnit další práci.

TDD a testování jednotek nejsou totéž.

Můžete napsat kód a později přidat testy jednotek. To není TDD a je to spousta práce navíc.

TDD je praxe kódování ve smyčce červeného světla. Zelené světlo. Iterace refaktorů.

To znamená psaní testů na kód, který ještě neexistuje, sledování selhání testů, oprava kódu, aby testy fungovaly, a pak se kód "správně". To vám často ušetří práci

Jednou z výhod TDD je, že snižuje potřebu přemýšlet o maličkosti. Věci, jako jsou chyby typu off-by-one, zmizí. Nemusíte procházet dokumentaci API, abyste zjistili, zda seznam, který vrací, začíná na 0 nebo 1, prostě to udělejte.

8
Paul Butcher

Pracoval jsem na systému, kde jsme testovali téměř všechno. Pozoruhodné popravy k testování byly PDF a XLS výstupní kód).

Proč? Podařilo se nám otestovat části, které shromáždily data, a postavit model, který byl použit k vytvoření výstupu. Také jsme byli schopni otestovat části, které zjistily, které části modelu by šly k souborům PDF=. Nebyli jsme schopni otestovat, zda PDF = = vypadalo dobře, protože to bylo naprosto subjektivní. Nebyli jsme schopni otestovat, že všechny části v PDF byly čitelné typický uživatel, protože to bylo také subjektivní) Nebo pokud byl výběr dat mezi sloupcovými a výsečovými grafy správný pro datový soubor.

Pokud bude výstup subjektivní, existuje jen malé testování jednotek, abyste mohli dělat, co stojí za námahu.

3
sal

U mnoha věcí trvá test „write-then-manual-test“ déle než psaní několika testů. Úspora času spočívá v tom, že tyto testy lze kdykoli znovu spustit.

Přemýšlejte o tom: Pokud máte s testem nějaké slušné pokrytí funkcí (nezaměňujte se s pokrytím kódu) a řekněme, že máte 10 funkcí - kliknutím na tlačítko znamená, že máte zhruba 10 yous opakované testy ... zatímco si sedíte a usrkáváte kávu.

Také nemusíte testovat minuty. Můžete si napsat integrační testy, které se týkají vašich funkcí, pokud se nechcete dostat do detailů oplzlého drsného ... IMO, některé testy jednotek jsou příliš jemně testovány na jazyk a platformu, ne na kód.

TL; DR Je to opravdu nikdy vhodné , protože výhody jsou prostě příliš dobré.

2
Steven Evers

Zde jsou dvě velmi dobré odpovědi:

  1. Kdy provést jednotkový test vs manuální test
  2. Co netestovat, pokud jde o testování jednotek?

Zdůvodnění vyhnutí se vnímané režii:

  • Okamžitá úspora času/nákladů pro vaši společnost
  • Potenciální úspora času/nákladů při řešení problémů/údržbě/rozšíření v dlouhodobém horizontu, i když jste pryč.

Nechtěli byste ze své strany nechat skvělý produkt jako důkaz kvality své práce? Když mluvíme sobecky, není to pro tebe lepší?

2
Aditya P

Profesionální vývojáři píšou testy jednotek, protože z dlouhodobého hlediska šetří čas. Chystáte se otestovat váš kód dříve nebo později, a pokud to vaši uživatelé neučiní, a pokud budete muset opravit chyby později, bude obtížnější je opravit a budou mít větší vliv na efekty.

Pokud píšete kód bez testů a nemáte žádné chyby, pak je v pořádku. Nevěřím, že můžete napsat netriviální systém s nulovými chybami, takže předpokládám, že to testujete tak či onak.

Jednotkové testy jsou také zásadní, aby se zabránilo regresím, když upravujete nebo upravujete starší kód. Neučiní dokázat vaše změna nezlomila starý kód, ale dává vám velkou důvěru (pokud samozřejmě projdou :))

Nechtěl bych se vrátit a napsat celou dávku testů na kód, který jste již dodali, ale až budete příště muset upravit funkci, kterou bych navrhl pokusit se napsat testy pro tento modul nebo třídu, získejte pokrytí až o 70% + před provedením jakýchkoli změn. Uvidíme, jestli ti to pomůže.

Pokud to zkusíte a můžete upřímně říci, že to nebyla žádná pomoc, pak je to spravedlivé, ale myslím si, že existuje dostatek důkazů o tom, že jim to pomůže, aby to alespoň stálo za to, když vyzkoušíte přístup.

2
Steve

Vypadá to, že většina odpovědí je pro-TDD, i když se otázka neptal na TDD, ale na testy jednotek obecně.

Za tím, co testovat jednotku nebo ne testovat jednotku, neexistuje zcela objektivní pravidlo. Ale existuje několik případů, kdy se zdá, že mnoho programátorů test jednotky neuskutečňuje:

  1. Soukromé metody

V závislosti na vaší filozofii OOP) můžete vytvořit soukromé metody k oddělení složitých rutin od vašich veřejných metod. Veřejné metody jsou obvykle určeny k tomu, aby byly volány na mnoha různých místech a často používány, a soukromé metody jsou pouze ve skutečnosti jedna nebo dvě veřejné metody ve třídě nebo modulu, aby bylo něco velmi specifického. Obvykle stačí napsat jednotkové testy pro veřejné metody, ale nikoli základní soukromé metody, které způsobí, že se některá magie stane. Pokud se něco pokazí u soukromé metody by měly být vaše testy veřejné metody dostatečně dobré, aby tyto problémy odhalily.

  1. Věci, které již znáte, by měly fungovat (nebo věci testované někým jiným)

Mnoho nových programátorů se staví proti tomu, když se poprvé učí testovat, a domnívají se, že musí testovat každou vykonanou linii. Pokud používáte externí knihovnu a její funkčnost je autory dobře testována a dokumentována, je obvykle zbytečné testovat konkrétní funkčnost v jednotkových testech. Například někdo může napsat test, aby se ujistil, že jeho model ActiveRecord přetrvává správnou hodnotu pro atribut s zpětným voláním „before_save“ do databáze, přestože samotné chování je již důkladně testováno v Rails. Metoda (metody), kterou callback volá, možná, ale ne samotné chování zpětného volání. Jakékoli základní problémy s importovanými knihovnami by bylo lepší odhalit spíše prostřednictvím akceptačních testů než jednotkových testů.

Oba by mohli platit, ať už děláte TDD nebo ne.

1
Ravenstine

Ken, já a mnoho dalších vývojářů jsme dospěli ke stejnému závěru jako vy několikrát během naší kariéry.

Pravda, že věřím, že najdete (stejně jako mnoho dalších) je, že počáteční investice do psaní testů pro vaši aplikaci se může zdát skličující, ale pokud budou psány dobře a zacíleny na správné části kódu, mohou opravdu ušetřit tunu času.

Můj velký problém byl s dostupnými testovacími rámci. Nikdy jsem se necítil, jako by to, co jsem hledal, tak jsem jen převalil své velmi jednoduché řešení. Pomohlo mi to přivést mě na „temnou stránku“ regresního testování. Podělím se o základní pseudo úryvek toho, co jsem zde udělal, a doufejme, že najdete řešení, které pro vás bude fungovat.

public interface ITest {
    public string Name {
        get;
    }
    public string Description {
        get;
    }
    public List<ITest> SubTests {
        get;
    }
    public TestResult Execute();
}

public class TestResult {
    public bool Succesful {
        get;
        set;
    }

    public string ResultMessage {
        get;
        set;
    }

    private Dictionary<ITest, TestResult> subTestResults = new Dictionary<ITest, TestResult>();
    public Dictionary<ITest, TestResult> SubTestResults {
        get {
            return subTestResults;
        }
        set {
            subTestResults = value;
        }
    }
}

Jedinou komplikovanou částí poté je zjistit, jakou úroveň granularity si myslíte, že je nejlepším „třeskem za babku“ pro jakýkoli projekt, který děláte.

Vytváření adresáře bude vyžadovat mnohem méně testování než podnikový vyhledávací stroj, ale základy se ve skutečnosti nezmění.

Hodně štěstí!

0
Adam Carstensen