Chcete-li otestovat systém A, izolovejte vedlejší účinky

Odstranění vedlejších účinků je jedním z nejlepších způsobů, jak vytvořit testovatelný kód

Obrázek boxerského zápasu dvou mužských bojovníků. Jejich obličeje jsou mimo rám. Bojovník na levé straně vyslal levý hák k bojovníkovi na pravé straně. Bojovník vpravo má na sobě červenou zkratku s malým symbolem Sovětského svazu.

Nock je slavná knihovna napsaná v JavaScriptu, která je užitečná pro potlačení síťových požadavků. Vrací statickou odpověď na testy, aby se mohly spustit, i když server HTTP není k dispozici.

Je to však také zápach.

Výsledné propojení mezi zdrojem dat a testovaným systémem je cena, která může ovlivnit refaktoring kódu a jeho udržovatelnost.

Tady je důvod.

Řekněme, že existuje server, který vrací seznam příspěvků a funkci, která spotřebovává odpověď z tohoto serveru a vytváří seznam titulů příspěvků. Test funkce používá Nock k oddělování odpovědi ze serveru:

Diagram, který ukazuje blok vlevo s titulkem „vytvořit seznam příspěvků“. Jedna šipka ukazuje na blok s titulkem „odešle odpověď“. Druhá šipka ukazuje na blok s titulkem „načíst“. Blok s titulkem „načíst“ má jednu šipku, která ukazuje ve směru bloku s titulkem „HTTP server“. Poslední šipka je přerušena štítkem „Nocked“.

Kód má slušné pokrytí. S tím však existují určité problémy.

Pokud změníte typ obsahu odpovědi, musíte změnit testy, i když chování kódu zůstává stejné:

Totéž platí, pokud změníte adresu URL, záhlaví nebo parametry, které Nock zadává. Testy musíte změnit, i když chování systému zůstává stejné:

Funkce „vytvořit seznam příspěvků“ je systém pod testem (SUT). Data z volání HTTP jsou zdrojem dat.

Kód můžete navrhnout tak, aby zdroj dat měl obecné rozhraní připojitelné k SUT. V takovém případě můžete použít logiku bez nutnosti přílišného nastavení.

Diagram, který ukazuje blok vlevo s titulkem „seznam titulů příspěvku“. Jedna šipka ukazuje na blok s titulkem „Zdroj dat v paměti“. Druhá šipka ukazuje na blok s titulkem „Data serveru HTTP“ Zdroj.

Pro testovací prostředí můžete vložit zdroj dat „do paměti“. Pro produkci můžete použít „zdroj dat serveru HTTP“.

„Obecné rozhraní“ v předchozím JSFiddle je metoda „najít název příspěvku.“ Bez ohledu na to, jak rozhraní sestavujete, máte kontrolu nad všemi volajícími. Změny jsou proto jednoduché. Martin Fowler to nazývá „nezveřejněné rozhraní“.

Na druhou stranu, pokud server poruší smlouvu na publikované rozhraní, řekněme, že se atribut třídy změní z názvu na článek, nadpisu, stačí změnit implementaci zdroje dat. Nemusíte provádět změny všude.

To, co je důležité otestovat a mít včasnou zpětnou vazbu, jsou testy proti chování, nikoli data. Proto je důležité navrhnout kód, aby se snížilo množství úsilí nezbytného pro změny logiky. V tomto případě je logika transformace vstupu ze zdroje dat do seznamu neuspořádaných HTML.

S novým designem jste odpojili zdroj dat od testovaného systému. Proto můžete Nock odebrat.

Nový design také snižuje práci nezbytnou pro přidání nového pravidla do systému bez kopírování / vkládání:

„Zdroj dat HTTP Server“ má přesto v rámci soukromé funkce „nettestovanou logiku“, „dotazuje název z html“.

Chcete-li to otestovat, můžete opakovat stejný vzorec. Zatlačte vedlejší účinky a zajistěte, aby byl mechanismus „vyžádání“ zapojitelný do „zdroje dat HTTP Server“. Tímto způsobem můžete stále testovat kód bez potřeby Nock:

Vzhledem k tomu, že již máte testy potvrzující, že název „seznamu příspěvků“ funguje s „zdrojem dat v paměti“, můžete se rozhodnout testovat zdroj dat izolovaně a ujistit se, že vrací správný výsledek:

Úplně jste vytlačili vedlejší efekt z logiky. V tomto případě je skutečná funkce „vyžádat žádost“ vedlejším účinkem. Nyní můžete použít Nock k pokrytí.

Avšak vzhledem k tomu, že logika uvnitř „požadavku na získání“ je triviální a Nock má značné náklady, má smysl mít malý počet integračních testů, které mohou provádět celou aplikaci, včetně vedlejšího účinku. Nock můžete použít k tomu, abyste se vyhnuli připojení k živému serveru, a přesto pomocí požadavků HTTP ověřte, zda aplikace vrátí přiměřenou odpověď, když se všechny kusy spojí dohromady.

Nock je užitečné oddělit připojení ve vrstvě HTTP a poskytnout statickou odpověď. Používejte jej však střídmě. Pro každý test, který se zakázaným inzerováním, zvýšíte významné propojení a náklady na změnu.

Pokud není používán střídmě, může Nock vytvořit Nock Hell.

Problém, který chcete vyřešit, je snížit počet chyb a náklady na změnu. Pokud změníte strukturu kódu beze změn chování, testy by se neměly přerušit. Pokud ano, nepodařilo se vám napsat užitečné testy.

Vaším cílem by mělo být zlepšit kvalitu testovacího pokrytí logiky, na které vám záleží, a dosáhnout včasné zpětné vazby. To vše bez ovlivnění vaší schopnosti změnit kód.

Izolovat vedlejší účinky a omezit použití nástrojů, jako je Nock, na hranice aplikace.

To by vám mělo poskytnout dostatek sebevědomí, abyste mohli provádět změny a neporušovat věci.

Připojte se k boji, potlačte vedlejší účinky a pak… Vyklepejte to.

Děkuji za přečtení. Pokud máte nějakou zpětnou vazbu, kontaktujte mě na Twitteru, Facebooku nebo Githubu.

Děkujeme Eduardu Slompovi a Guilherme J. Tramontině za jejich bystrou zpětnou vazbu k tomuto příspěvku.