Testování reducerů a async akcí bez integračního prostředí

From IT-Core
Jump to navigation Jump to search


Na závěr si osvojte práci s výjimkami. V nastavení devtools (ozubené kolečko v záložce Sources) zaškrtněte „Pause on exceptions". Jakmile dojde k chybě, kód se zastaví přesně na místě, kde vznikla, a vy vidíte celý zásobník volání. Tím okamžitě poznáte, která funkce chybu způsobila. Nebojte se také experimentovat – čím víc času strávíte v devtools, tím rychleji najdete chyby i u složitějších aplikací. Ladění není ztráta času, ale investice do kvalitnějšího kódu.

Dalším častým problémem je použití operátoru NOT IN na poddotaz. Ten často vede k sekvenčnímu procházení celé tabulky. Většinou ho jde přepsat pomocí LEFT JOIN a kontroly na NULL, nebo pomocí NOT EXISTS. Osobně dávám přednost NOT EXISTS, protože bývá srozumitelnější a databázový optimalizátor si s ním poradí lépe. Pokud máte dotaz, který spojuje mnoho tabulek, zkontrolujte, jestli všechny JOINy mají správné indexy na spojovacích sloupcích. Bez indexu se každé spojení mění v porovnávání každého řádku s každým – to je zpravidla hlavní příčina extrémní pomalosti.

Při týmové práci na projektu narazíte na problém, že každý vývojář má mírně odlišné nastavení editoru, formátování kódu nebo verze nástrojů. Výsledkem jsou zbytečné konflikty v gitu, nepřehledné diffy a ztráta času při ručním sjednocování. Ideální řešení spočívá v tom, že konfiguraci projektu uděláte součástí repozitáře, nikoli lokální záležitostí každého člena týmu. Tím zajistíte, že všichni pracují se stejným základem a případné úpravy procházejí code review.

Jak nastavit, aby konfigurace opravdu fungovala? Samotné přidání souborů nestačí, pokud je členové týmu nepoužívají. Zkuste do skriptů v package.json přidat příkazy pro kontrolu formátování a lintování, které se spustí při pre-commit hooku. Například pomocí husky a lint-staged můžete zajistit, že před každým commitnutím proběhne automatická kontrola. Tím se problém s nekonzistentním kódem eliminuje dřív, než se dostane do sdíleného repozitáře. Pokud někdo zkusí obejít hook, commit se nepovede a dotyčný musí chybu opravit.

Když je pokrytí pouhou iluzí bezpečí Hlavním problémem nastáosvětlení v obývákuá, když se pokrytí stane cílem samo o sobě. Pokud tým dostane za úkol zvýšit pokrytí na určitou hodnotu, začne psát testy, které pouze volají funkce, ale neověřují jejich návratové hodnoty ani chování v hraničních stavech. Typickým příkladem je test, který zavolá metodu, ale nepoužije žádný assert – takový test sice zvýší pokrytí, ale neodhalí žádnou chybu. Stejně tak testy, které používají pouze happy path, ignorují výjimky, prázdné vstupy nebo neočekávané kombinace parametrů. Výsledkem je statistika, která vypadá dobře, ale skutečná kvalita aplikace se nezlepšila.

Nakonec se vždy vyplatí sledovat skutečné vytížení databáze. Zapněte si logování pomalých dotazů a pravidelně ho kontrolujte. Uvidíte, které dotazy se opakují a trvají nejdéle. Soustřeďte se na ty, které se volají často – třeba v rámci jednoho requestu na webu. Vyplatí se také zvážit, zda některé výpočty neděláte opakovaně na místo toho, abyste si předpočítali hodnoty do pomocné tabulky. Tyto jednoduché kroky vám pomohou udržet databázi svižnou bez investic do další infrastruktury.

Druhým krokem je použití middleware, který automaticky odesílá akce pro začátek a konec asynchronní operace. Místo ručního psaní tří akcí pro každý požadavek si vytvořte jednoduchý middleware sledující akce s payloadem obsahujícím promise. Když takovou akci zachytí, odešle nejprve akci s příponou PENDING, pak počká na vyřešení promise a odešle akci s daty nebo chybou. Tím se reducery zbaví zodpovědnosti za řízení toku a budou jen reagovat na konkrétní typy. Vyhnete se také časté chybě, kdy se zapomenete postarat o selhání a aplikace zůstane ve stavu 'loading' navždy.

Další oblastí, kde se často dělá chyba, je ukládání celého asynchronního stavu do jediné části store. Mít zvlášť pole pro data, boolean pro loading a string pro chybu sice funguje, ale při mnoha operacích se to stane nepřehledným. Lepší je seskupit stav jedné asynchronní akce do jednoho objektu, který obsahuje data, stav a chybu. Můžete použít vzor, kdy každá asynchronní operace má svůj stav ve tvaru status: 'idle' . Tento přístup snižuje počet klíčů v reducers a usnadňuje testování, protože máte vše na jednom místě.

Typickým problémem, na který narazíte, je závod o odpovědi (race condition). Pokud uživatel rychle spustí dva podobné požadavky, může se stát, že odpověď z prvního přijde po druhém a přepíše novější data. Řešením je generovat s každou asynchronní akcí unikátní identifikátor a v reduceru kontrolovat, zda odpověď skutečně odpovídá poslednímu požadavku. Jednoduchým trikem je ukládat do stavu číslo requestId a při příchodu odpovědi porovnat, zda se shoduje s aktuálním. Tím zajistíte, že starší odpověď nebude mít vliv na stav, a předejdete podivným chybám v UI.

If you have any sort of concerns concerning where and how to make use of otevřít, you could contact us at the web-site.