Oprava testovacej sady

Testy závislé od poradia: ako ich nájsť a opraviť

Test prejde samostatne, no v celej sade zlyhá. Inokedy sa pokazí iba po konkrétnom scenári alebo po zapnutí paralelného behu. Za takým výsledkom často nie je náhodnosť, ale skrytá väzba medzi testmi. Nájsť ju znamená oddeliť dve podobné príčiny: závislosť od poradia a kolíziu pri súbehu.

Keď predchádzajúci test mení výsledok ďalšieho

Test je závislý od poradia, ak jeho výsledok ovplyvňuje stav po predchádzajúcom teste. Môže očakávať, že iný scenár najprv vytvorí používateľa, alebo naopak zdedí účet, košík či globálne nastavenie, ktoré predchodca zmenil. Problém sa prejaví aj pri jedinom workeri. Stačí prehodiť poradie.

Typickým príznakom je scenár, ktorý samostatne prejde na čistom prostredí, no zlyhá po jednom konkrétnom teste. Objaviť sa môže aj opačný prípad. Scenár prejde iba po „prípravnom“ teste, pretože si sám nevytvorí údaje, ktoré potrebuje.

Takáto väzba zhoršuje diagnostiku. Zlyhanie sa zobrazí v druhom teste, hoci príčinu vytvoril prvý. Pri spustení jedného scenára v editore sa chyba stratí a tím začne podozrievať CI alebo časovanie.

Závislosť od poradia nie je to isté ako kolízia pri súbehu

Pri kolízii dva testy menia rovnaký zdroj v rovnakom čase. Sériovo môžu prejsť v ľubovoľnom poradí, pretože každý pred použitím obnoví stav. Pri paralelnom behu sa však ich kroky preložia cez seba. Jeden worker vymaže súbor, obsadí pevný port alebo upraví účet práve vtedy, keď ho druhý používa.

Obe chyby majú spoločný koreň, ktorým je zdieľaný meniteľný stav. Diagnostika sa však líši. Zmena poradia odhalí stav prenesený z ukončeného testu. Zmena počtu workerov odhalí prekrytie dvoch stále bežiacich testov. Sériový beh preto nie je automaticky oprava. Môže len skryť kolíziu.

Playwright štandardne spúšťa testovacie súbory paralelne a testy v jednom súbore v poradí deklarácie. Jeho dokumentácia zároveň odporúča izolovať testy namiesto vytvárania vzájomne závislých sériových skupín. Poradie medzi súbormi navyše nie je pri paralelnom behu zaručené. Podrobnosti uvádza dokumentácia k paralelnému vykonávaniu v Playwrighte.

Príklad so spoločným účtom a košíkom

Predstavte si dva E2E scenáre, ktoré používajú účet e2e-shopper@example.test. Test A košík vyprázdni, pridá stolnú lampu a overí výslednú cenu. Po skončení položku neodstráni. Test B sa prihlási do rovnakého účtu a overí, že prázdny košík zobrazuje odkaz na katalóg.

Test B samostatne prejde. Ak však beží po teste A, nájde v košíku lampu a zlyhá. Opačné poradie prejde, pretože test A si košík na začiatku vyčistí. To je závislosť od poradia. Stav z dokončeného testu A prenikol do testu B.

Teraz upravme test B tak, aby si na začiatku tiež vyprázdnil košík a potom pridal kancelársku stoličku. Oba testy sériovo prejdú v ľubovoľnom poradí. Pri súbehu môže B vyprázdniť košík po tom, čo A vložil lampu. Test A potom nevidí očakávanú položku alebo test B nájde oba produkty. To je kolízia pri súbehu. Samotné prehadzovanie poradia ju nemusí vyvolať.

Rovnaký vzorec vzniká pri zdieľanom používateľovi, objednávke, kupóne, databázovom zázname, adresári s exportom alebo pevnom porte lokálnej služby.

Diagnostická matica namiesto náhodných opakovaní

Pred experimentom zachovajte commit, zostavenie aplikácie, konfiguráciu, dáta a verzie nástrojov. Potom meňte iba spôsob spustenia. Krátka matica pomôže premeniť neurčitý pád na konkrétnu hypotézu.

Spustenie Čo sledujete Pravdepodobný záver
Podozrivý test samostatne na známom stave Či potrebuje cudziu prípravu alebo už zlyháva sám Zlyhanie ukazuje na vlastný setup, aplikáciu alebo prostredie
Podozrivý test hneď po možnom predchodcovi Či stav po prvom teste zmení výsledok druhého Opakovateľný rozdiel podporuje závislosť od poradia
Rovnaká dvojica v opačnom poradí Či problém sleduje konkrétnu následnosť Jedno chybné poradie ukazuje, kto stav zanecháva alebo očakáva
Celá cieľová skupina sériovo Či zlyhanie zmizne bez časového prekrytia Zlepšenie je stopa ku kolízii, nie hotová oprava
Rovnaká skupina s plánovaným súbehom Či sa testy bijú o účet, súbor, port alebo záznam Pád iba pri súbehu podporuje hypotézu o kolízii

Ku každému behu uložte prvú chybu a identifikátory použitých údajov. Pri košíku zaznamenajte účet, ID behu, worker a položky pred každým rozhodujúcim krokom. Snímka stránky bez týchto údajov ukáže prejav, nie vlastníka zmeny.

Meňte jednu podmienku

Ak súčasne zmeníte poradie, počet workerov, účet a cleanup, zelený výsledok nič presné nepotvrdí. Začnite jednou vetou, napríklad: „Test B zlyhá, keď test A nechá položku v spoločnom košíku.“ Potom nechajte oba testy aj aplikáciu bez zmien a prehoďte iba poradie.

Pri hypotéze o súbehu ponechajte dáta aj poradie a zmeňte iba počet workerov. Ak chcete potvrdiť konflikt účtu, v ďalšom experimente zachovajte cieľový súbeh a prideľte jednému testu iný účet. Výsledok by mal sledovať práve túto jednu podmienku. Tento postup nadväzuje na širšiu diagnostiku situácie, keď testy lokálne prejdú, ale v CI padajú.

Každý test si pripraví vlastný počiatočný stav

Trvalá oprava začína explicitnou prípravou. Test B nemá predpokladať prázdny košík ani čakať, že ho vyčistí test A. Má si vytvoriť zákazníka s prázdnym košíkom alebo stav nastaviť cez cielené API či fixture. Ak je vytvorenie košíka predmetom testu, použite používateľské rozhranie. V ostatných prípadoch býva priama príprava cez testovacie rozhranie kratšia a presnejšia.

Meniteľné dáta priraďte testu alebo workeru. Identifikátor môže obsahovať ID behu, názov scenára a index workera, aby sa dal nájsť v databáze aj reporte. Stabilný katalóg možno zdieľať, ak ho testy iba čítajú. Účet, košík alebo kupón, ktorý scenár mení, spoločný zostať nemá. Praktický návrh rozoberajú testovacie dáta pre E2E testy.

Aj Selenium odporúča nezdieľať testovacie dáta, odstrániť staré údaje, ktoré by mohol prevziať ďalší test, a vytvoriť pre každý test samostatnú inštanciu WebDrivera. Vlastné dáta pritom neznamenajú kópiu celej databázy pre každý scenár. Oddeľte iba stav, ktorý sa mení.

Izolujte prehliadač, súbory aj porty

Nový účet nevyrieši cookies po predchádzajúcom prihlásení. Playwright vytvára pre každý test izolovaný browser context, teda profil podobný anonymnému oknu s vlastnými cookies, lokálnym úložiskom a úložiskom relácie. Ak si však tím ručne ponechá jednu stránku alebo context pre viac testov, túto hranicu obíde. Čistý context zároveň neoddelí údaje v spoločnom backende.

Pri Seleniu používajte nový driver pre každý test a po behu ho ukončite aj pri zlyhaní. Dokumentácia odporúča čerstvý prehliadač pre každý test, pričom nová inštancia bežného ovládača štandardne začína s novým používateľským profilom.

Rovnakú hranicu potrebujú zdroje mimo prehliadača. Export ukladajte do adresára konkrétneho testu, nie do spoločného downloads/report.csv. Dočasný súbor pomenujte identifikátorom behu. Lokálnym serverom prideľte port cez koordinovaný mechanizmus alebo z rozsahu vyhradeného pre daný beh a worker. Všetky procesy sa nemôžu spoliehať na rovnaký pevný port.

Cleanup je poistka, nie predpoklad ďalšieho testu

Cleanup spúšťajte aj po neúspechu a obmedzte ho na záznamy, ktoré vlastní daný test alebo beh. Mal by sa dať bezpečne zopakovať a jeho chyba nesmie prekryť pôvodné zlyhanie. Pred vymazaním uchovajte ID potrebné na diagnostiku.

Nasledujúci test sa napriek tomu nesmie spoliehať, že cleanup predchodcu prebehol. Worker môže byť ukončený, služba môže počas teardownu prestať odpovedať a niektoré účinky, napríklad odoslaný e-mail, sa nedajú vrátiť. Vlastný explicitný setup je prvá obranná vrstva. Cielený cleanup chráni prostredie pred hromadením dát.

Kedy sekvenčný workflow patrí do jedného testu

Nie každá následnosť krokov je chybná. Používateľ môže vytvoriť objednávku, zaplatiť ju a potom požiadať o vrátenie peňazí. Ak je predmetom overenia celý tento workflow a každý krok potrebuje výsledok predošlého, zapíšte ho ako jeden test s jedným príbehom, stavom a výsledkom.

Rozdelenie takej cesty na tri testy vytvorí reťaz, v ktorej nemožno druhú časť spoľahlivo spustiť samostatne. Zlyhanie platby navyše znehodnotí výsledok testu vrátenia. Kroky môžete presunúť do čitateľných pomocných funkcií, no vlastníkom životného cyklu zostane jeden test. Samostatné testy zachovajte pre prípady, ktoré si vedia pripraviť zaplatenú objednávku bez závislosti od iného scenára.

Ako overiť opravu

Opravený test spustite samostatne na známom stave, po pôvodnom predchodcovi a v opačnom poradí. Potom zopakujte cieľovú skupinu sériovo aj s rovnakým počtom workerov, aký používa CI. Neoverujete iba zelený výsledok. Skontrolujte aj to, či každý test použil vlastné ID, adresár, port a prehliadačovú reláciu a či po behu zostali iba zámerne zachované dáta.

Pôvodnú chybnú podmienku si ponechajte ako reprodukčný experiment. Ak dvojica so spoločným účtom stále spoľahlivo zlyhá a dvojica s oddelenými účtami pri rovnakom súbehu prejde, príčina je podstatne lepšie doložená než jedným úspešným retry. Pri širšej sade sledujte výsledky prvých pokusov a zlyhania zoskupujte. Postup opisuje článok ako zistiť, ktoré testy sú nestabilné.

Čo tým získate

Nezávislé testy sa dajú spustiť jednotlivo, v inom poradí aj paralelne. Výsledok potom opisuje správanie aplikácie v známom stave, nie históriu košíka či adresára po inom scenári. Tím môže skrátiť beh bezpečným súbehom a pri zlyhaní hľadá príčinu v menšom priestore.

Ďalší krok

Vyberte dvojicu, pri ktorej jeden test samostatne prejde a v sade padá. Prejdite päť režimov z diagnostickej matice a zapíšte príčinu ako „podmienka, mechanizmus, prejav“. Potom oddeľte meniteľné dáta a zopakujte pôvodnú chybnú podmienku. Ak podobné väzby zasahujú väčšiu časť sady, ozvite sa nám. Pomôžeme ich zmerať, opraviť a vrátiť testy do pravidelného CI behu.

Súvisiace témy

Mohlo by vás zaujímať

Spoľahlivé výsledky sú dôležitejšie než počet testov

Zmeriame nestabilitu, preveríme pravdepodobné príčiny náhodných zlyhaní a sadu stabilizujeme v dohodnutom rozsahu.