Co się stane, když reducery otestuješ bez běžícího serveru
Asynchronní akce bez serveru Async akce nejsou nic jiného než funkce, které postupně volají dispatch. K jejich testování nepotřebuješ běžící backend. Stačí vytvořit falešný dispatch a falešnou funkci, která vrací slib. Zavolej thunk s těmito závislostmi a ověř, které akce byly odeslány a v jakém pořadí. Pokud thunk používá axios nebo fetch přímo v těle, bude se testovat obtížně. Řešením je předat klienta jako argument nebo použít injektáž závislostí.
Začněte pojmenováním. Proměnná data neříká nic, seznamUzivatelu říká všechno. Funkce process() nutí čtenáře otevřít tělo funkce, vypocitejSlevu() ho pustí dál. Platí přitom jedno pravidlo: pokud název potřebuje komentář, je název špatný. Komentáře mají vysvětlovat proč, ne co. Když vidíte // zvyšujeme o jedna nad i++, komentář jen opakuje kód a za měsíc bude lhát.
Posledním krokem je kontrola před začátkem sprintu. Projděte si každý úkol a ověřte, že je opravdu nezávislý a že jeho dokončení lze demonstrovat. Pokud ne, rozložte ho ještě jednou. Menší úkoly se snáze odhadují, rychleji odhalují problémy a umožňují pružně reagovat, když se něco zvrtne. To je celý přínos: místo jednoho nejistého odhadu máte sadu ověřitelných kroků.
Testovací pyramida vznikala v době, kdy se požadavky měnily pomalu a vydání jednou za čtvrt roku bylo normální. Dnes se ale rozsah funkcí upravuje průběžně, priority se přesouvají a to, co bylo minulý měsíc kritické, může být dnes zbytečné. Pokud na to pyramida nereaguje, začne pokrývat něco jiného, než tým skutečně potřebuje. Řešení není pyramida zrušit, ale nastavit pravidla, podle kterých se její vrstvy posouvají spolu s požadavky.
Vyhýbejte se sdílenému mutovatelnému stavu, kde to jde. Globální proměnné a objekty předávané mezi funkcemi, které je mění, dělají tok dat nepředvídatelným. Pokud funkce vrací novou hodnotu místo toho, aby přepisovala vstup, snáz se testuje a snáz se čte. Stejně tak dávejte přednost malým modulům s jasně vymezeným rozhraním před jedním velkým souborem, kde se všechno odkazuje na všechno.
Odhad celého uživatelského příběhu nebo větší funkce je vždy zatížený chybou. Čím delší je odhadovaný čas, tím větší je nejistota. Řešením není odhadovat lépe, ale odhadovat menší celky. Sprint pak stojí na konkrétních krocích, které lze skutečně dokončit a ověřit.
U asynchronních testů platí dvě pravidla. Vždy vrať slib z testu, aby ho runner počkal. A vždy ošetři obě větve – úspěch i chybu. Typická chyba je testovat jen stav po dokončení, ale ne to, co se stalo během čekání. Ověř, že se dispatch volá ve správném okamžiku a že se po chybě neposílá akce pro úspěch. Pokud používáš thunk, testuj ho jako obyčejnou funkci; žádný store k tomu nepotřebuješ.
Redux je navržený tak, že většinu logiky lze ověřit bez jakéhokoli integračního prostředí. Reducer je čistá funkce: dostane stav a akci, vrátí nový stav. Žádné API, žádná databáze, žádný prohlížeč. Pokud tomu tak není, problém není v testech, ale v návrhu. Prvním krokem je proto rozdělit kód na dvě části: čistou logiku přechodů stavů a vedlejší efekty, které patří do middlewaru nebo thunků.
U každého malého úkolu odhadněte čas zvlášť a sečtěte. Pokud součet přesahuje kapacitu sprintu, neškrtejte úkoly naslepo. Raději zmenšete rozsah příběhu nebo přesuňte část do dalšího sprintu. Vyhnete se tak tlaku na přesčasy, který vzniká, když se velký odhad rozdělí až během práce.
Na závěr: agilní metodiky s externími dodavateli nefungují samy od sebe. Je potřeba je přizpůsobit tak, aby respektovaly hranice firem, ale zároveň vytvořily jeden společný pracovní tok. Pomůže jasná dohoda o rolích, společný rytmus dodávek, písemná i ústní komunikace a především ochota obou stran přiznat problémy dřív, než se z nich stanou konflikty.
Nakonec si dej pozor na dvě věci. Nesnaž se testovat implementační detaily, jako je počet volání dispatch, pokud to není součástí kontraktu. A nepodceňuj testy chybových stavů – právě tam vzniká většina regresí. Když reducer i async akce pokryješ bez serveru, získáte rychlou a spolehlivou sadu, která odhalí chybu dřív, než se dostane do integrace.
Rozdělujte podle výstupu, ne podle času Častou chybou je dělit práci podle hodin. „Udělám to za čtyři hodiny" nic neříká o tom, co bude hotové. Místo toho se ptejte, co konkrétního bude na konci úkolu existovat: návrh schématu, opravená chyba, nasazená změna. Výstupní dělení přirozeně odhalí skrytou práci, jako je čekání na review, testování nebo komunikace se závislostmi.
Test reduceru začni tím, že zavoláš funkci se dvěma argumenty: výchozím stavem a akcí. Porovnej výsledek pomocí hluboké rovnosti. Nezapomeň testovat i neznámou akci – reducer musí vrátit původní stav, ne undefined. Častá chyba je mutace: vývojář upraví pole přes push a test projde, protože stejná reference zůstane. Proto po každém testu ověř, že se původní objekt nezměnil, ideálně tak, že si před voláním uložíš kopii a porovnáš ji.