Najčastejšie chyby v Cypress a ako sa im vyhnúť

Ak si IT tester a využívaš Cypress na testovanie webových aplikácií, zrejme si sa už stretol s radom špecifických výziev. Nie je to nič neobvyklé, pretože testovanie nie je práve bezproblémová jazda. V tomto článku poukážeme na niektoré z bežných chýb pri písaní testov a ponúkneme ti rady, ako sa im vyhnúť.

1. Chyby spojené s asynchrónnym správaním

Pri práci so Cypressom je dôležité pochopiť, že mnoho jeho operácií je asynchrónnych. Kód teda nečaká na dokončenie operácie predtým, než prejde k ďalšiemu riadku. To môže spôsobiť problémy v testoch, pretože sa môžeš pokúšať interagovať s elementmi, ktoré ešte neboli načítané alebo zmenené.

 

Pre riešenie týchto problémov sa odporúča používať Cypress príkazy, ako je cy.get(), cy.wait(), a cy.then(). Tieto príkazy pomáhajú riadiť asynchrónne operácie a zabezpečia, že na svoje testy sa môžeš spoľahnúť.

1. cy.get()

Tento príkaz sa používa na získanie jedného alebo viacerých DOM elementov. cy.get() automaticky čaká na elementy, kým nebudú existovať v DOM.

Napríklad:

<strong>cy</strong>.get('.button').click();

V tomto príklade sa čaká, kým sa tlačidlo s classou .button neobjaví v DOM, a až potom na neho klikne.

2. cy.wait()

Cypress príkaz cy.wait() efektívne rieši asynchrónne správanie v testoch. Umožňuje explicitné čakanie na dokončenie sieťových požiadaviek, ako sú AJAX volania, prostredníctvom nastavenia aliasov a časových limitov. Týmto prístupom Cypress zabezpečuje, že testy pokračujú až po dokončení asynchrónnych procesov.

Napríklad:

cy.intercept('GET', '/some-endpoint').as('networkRequest');
// Najskôr nastavíme interceptor na zachytenie požiadavky 
cy.wait('@networkRequest');
// Potom použijeme cy.wait() za účelom čakania na dokončenie tejto požiadavky

V tomto príklade cy.intercept (‚GET‘, ‚/some-endpoint‘).as(‚networkRequest‘) najskôr nastavíme interceptor na odchytenie GET požiadavky pre endpoint /some-endpoint a pridelíme mu alias networkRequest.

Následne cy.wait(‚@networkRequest‘) povie Cypressu, aby počkal na dokončenie požiadavky s aliasom networkRequest.

Odporúčame ti...

Čo je to AJAX požiadavka?

AJAX je technika vo webovom vývoji umožňujúca posielať a prijímať dáta z web servera bez nutnosti načítať celú stránku. Umožňuje tak aktualizovať časti webovej stránky nezávisle.

3. cy.then()

Cypress príkaz cy.then() je esenciálny pre prácu s asynchrónnym správaním v testoch. Jeho hlavnou úlohou je zabezpečiť, že sa kód vo vnútri callback funkcie sa spustí až po dokončení všetkých predchádzajúcich Cypress príkazov v reťazci. Pomocou cy.then() môžeš získať výsledky predchádzajúcich príkazov, čo je užitočné pre ďalšie overovanie alebo manipuláciu s testovanými prvkami.

Napríklad:

cy.get('.message').then((element) => {
  // Priamo porovnávame text elementu s očakávaným textom
  expect(element.text()).to.equal('Očakávaný text');
});> {
 // manipulácia s položkami zoznamu
})

V tomto príklade cy.get(‚.message‘) najprv vyhľadá element s triedou .message. Potom sa cy.then() použije na vykonanie funkcie, ktorá berie tento element ako argument. Namiesto ukladania textu elementu do premennej, tento príklad priamo porovnáva text elementu s očakávaným textom pomocou expect().to.equal(). Tento spôsob je efektívny na overenie, či obsah elementu spĺňa určité kritériá.

2. Zanedbávanie časových limitov

Cypress má svoje predvolené časové limity pre rôzne operácie, ako napríklad 4 sekundy pre cy.get(), cy.find(), cy.wait() a ďalšie. Je dôležité, aby si vedel, ako tieto limity ovplyvňujú chovanie tvojich testov.

Časové limity si môžeš prispôsobiť na globálnej úrovni v konfiguračnom súbore Cypress, ktorý je typicky cypress.json. Toto ti umožňuje nastaviť limity, ktoré zodpovedajú špecifikám tvojej aplikácie.

Odporúčame ti...

Pozor na príliš krátke limity alebo príliš dlhé limity!

Nastavenie príliš krátkych limitov môže spôsobiť, že tvoje testy zlyhajú, pretože nie vždy sa aplikácia alebo server odpovie dostatočne rýchlo. Na druhej strane, nastavenie príliš dlhých časových limitov môže spomaliť celkový beh testov. V niektorých prípadoch môžeš použiť rôzne časové limity pre rôzne testy alebo časti testov. Napríklad, môžeš si nastaviť kratší časový limit pre jednoduché DOM operácie a dlhší pre testy, ktoré zahŕňajú sieťové požiadavky alebo zložité transakcie.

// Príklad nastavenia globálneho časového limitu v cypress.json
{
  "defaultCommandTimeout": 10000, // 10 sekúnd pre všetky príkazy
  "requestTimeout": 15000 // 15 sekúnd pre sieťové požiadavky
}

// V testovacom súbore
describe('Testovanie webovej stránky s nastavením časového limitu', () => {
  it('Testuje rýchle DOM operácie', () => {
    cy.visit('http://example.com');
    cy.get('.quick-element', { timeout: 5000 }).should('be.visible'); // Kratší časový limit pre rýchle DOM operácie
  });

3. Nesprávna selekcia elementov

Nesprávne identifikované alebo prehliadnuté elementy vedú k nesprávnym výsledkom testov, čo môže maskovať chyby alebo nesprávne označiť funkčné časti ako chybné. Toto nielenže zvyšuje riziko prehliadnutia kritických problémov, ale tiež vedie k zvýšenej krehkosti testov. Testy sa stávajú náchylnými na zlyhanie pri menších zmenách v aplikácii, čo vyžaduje časté revízie a zvyšuje nároky na údržbu testov.

Ako selektovať elementy v Cypress:

  1. Data atribúty – Odporúča sa používať vlastné dátové atribúty, ako je data-cy, data-test, alebo data-testid. Tento prístup oddelí testovacie selektory od CSS a JS, čo zvyšuje stabilitu testov.
  2. Používanie Unikátnych Selektorov: Ak nie sú dostupné dátové atribúty, môžeš použiť CSS selektory. Snaž sa vyhnúť veľmi špecifickým alebo zložitým selektorom, ktoré môžu byť náchylné na zmeny v dizajne. Selektovanie elementov podľa ID je tiež dobrá metóda, pokiaľ sú ID stabilné a jedinečné.
Odporúčame ti...

Pri používaní selektorov class a ID je tu riziko, že zmeny v dizajne alebo štruktúre webu môžu spôsobiť zlyhanie testov, pretože tieto selektory sa často menia pri aktualizáciách. Selektory nemusia byť dostatočne špecifické alebo môžu spôsobiť konflikty, ak sú použité na viacerých miestach, čo vedie k nesprávnemu vyhodnoteniu testov. Navyše, táto metóda vytvára závislosť testov od vizuálnych aspektov aplikácie, čo môže znížiť ich robustnosť a udržateľnosť.

Napríklad:

// Použitie data atribútov
cy.get('[data-cy=login-button]').click();

// Použitie unikátneho selektora
cy.get('#submit-button').click();

4. Nevyužívanie vlastných príkazov (Custom commands)

Mnohí testeri nevyužívajú možnosti vytvárania vlastných príkazov v Cypresse. Custom commands umožňujú centralizovať a znovu použiť kód, čo zvyšuje efektivitu a znižuje riziko chýb v testoch. Vďaka nim môžeš mať konzistentnejšie a ľahšie udržiavateľné testovacie skripty. Tejto téme sme sa venovali v zvláštnom článku Custom commands Cypress.

Vytváranie vlastných príkazov je jednoduché a môže výrazne zlepšiť čitateľnosť a údržbu testov. Napríklad, ak často testuješ prihlásenie do aplikácie, môžeš vytvoriť príkaz login, ktorý toto bude robiť za teba.

// V súbore commands.js
Cypress.Commands.add('login', (email, password) => {
  cy.get('input[name=email]').type(email);
  cy.get('input[name=password]').type(password);
  cy.get('form').submit();
});

// V testovacom súbore
cy.login('user@example.com', 'password123');

Toto je len príklad, ako sa dá tento koncept využiť. Využitím vlastných príkazov môžeš zefektívniť testovanie a zjednodušiť údržbu svojich testovacích skriptov.

5. Nedostatočná izolácia testov

Pri nedostatočnej izolácii testov v Cypress sa môžeš stretnúť s problémom nejednoznačných a nepredvídateľných výsledkov. Ak tvoje testy nie sú dostatočne izolované, výsledok jedného testu môže ovplyvniť výsledok iného. To znamená, že ak jeden test zmení stav aplikácie alebo databázy, môže to spôsobiť, že nasledujúce testy zlyhajú alebo prejdú, ale nie kvôli správnym dôvodom. Je dôležité, aby bol každý test navrhnutý tak, aby bol samostatný a nezávislý na ostatných, by boli výsledky tvojich testov spoľahlivejšie a konzistentnejšie

Ako dosiahnuť lepšiu izoláciu testov v Cypress?

  1. Resetovanie stavu aplikácie: Na začiatku každého testu používaj príkazy ako cy.visit(), aby si zresetoval stav aplikácie. To ti pomôže začať každý test s čistým štítom.
  2. Čistenie po testoch: Po každom teste sa uisti, že dôjde k čisteniu. Napríklad odstráň testovacie údaje, aby si predišiel ich ovplyvneniu na ďalšie testy.
  3. Používanie mockov a stubov: Na simulovanie API volaní alebo externých služieb využívaj mocky a stuby. Týmto spôsobom sa tvoje testy nestanú závislými na externých faktoroch a výsledky budú konzistentnejšie. (Prečítaj si aj článok Cypress API testing.)
  4. Nezávislé testovacie scenáre: Navrhuj svoje testy tak, aby každý bol samostatným scenárom, ktorý nezávisí na výsledkoch iných testov. Tým zabezpečíš, že každý test je izolovaný a overuje iba to, čo má.
  5. Prečítaj si aj o ladení testov – debbugingu v Cypress.

Záver

Pamätaj, že každý problém, s ktorým sa stretneš pri testovaní, je príležitosťou na zlepšenie a naučenie sa niečoho nového. S týmito tipmi budeš schopný riešiť bežné problémy, s ktorými sa stretávaš pri práci s Cypressom a zvýšiš tak efektivitu a spoľahlivosť tvojich testov. Aktualizuj svoje znalosti a nezabudni navštíviť oficiálnu dokumentáciu Cypress (cypress documentation) na ich webových stránkach. Tu nájdeš podrobné návody a najnovšie aktualizácie, ktoré ti pomôžu zostať na špičke softvérového testovania.

Ak si software tester a vieš po nemecky, prezri si naše benefity pre zamestnancov a reaguj na najnovšie ponuky práce.

O autorovi

Katarína Kučáková

Software Test Engineer

Moja cesta k testovaniu softvéru sa začala v roku 2019 až po štúdiu ekonómie a pracovných skúsenostiach v iných odvetviach. To mi pomohlo vnímať IT svet v rôznych súvislostiach. Ten totiž ponúka neustále nové výzvy, pre ktoré rada hľadám riešenia. Obľubujem oddych pri čítaní, turistiku alebo lyžovanie. LinkedIn

Daj nám o sebe vedieť