consdata.com
Blog techniczny Blog biznesowy Dział HR
EN
Cypress

Testy e2e z Cypress

author Adrian Marszałek
24 listopada 2020

Łamy bloga Consdata Tech gościły już wiele wpisów dotyczących testowania aplikacji - jednak żaden z nich nie zajmował się tematem testów e2e (end-to-end). Na rynku testów e2e, czyli takich, które sprawdzają funkcjonalność od początku do końca, symulując zachowanie użytkownika i weryfikując UI, stale dominuje Selenium - narzędzie wielu programistom znane, z historią sięgającą 2004 roku. Dziś na warsztat wezmę dość młody framework - Cypress, który może okazać się kuszącą alternatywą dla wcześniej wspomnianego narzędzia.

Kilka słów o Cypress

Należy zacząć od tego, że Cypress nie jest nakładką na Selenium - jest to całkowicie niezależny byt, zbudowany na JavaScript. Również pisanie testów odbywa się w tym języku, a jeśli ktoś miał wcześniej styczności z narzędziami takimi jak Chai, czy Mocha, to będzie czuł się jak w domu - Cypress zaadoptował i dopasował wykorzystywane przez nie rozwiązania do swoich potrzeb.

Wykonywane scenariusze testowe mogą być przez nas podglądane na żywo - są one uruchamiane na wybranej przez nas przeglądarce, może to być Edge, Chrome, Firefox lub wbudowany Electron. Podczas ich wykonywania każdy kolejny krok zapisywany jest pod postacią snapshotów - migawek, do których możemy zajrzeć w każdym momencie i zweryfikować stan aplikacji. Przez to, że Cypress uruchamiany jest w naturalnym środowisku twojej aplikacji, możemy korzystać ze wszystkich dobrodziejstw nowoczesnych DevToolsów: od debugowania kodu, poprzez kontrolę sieci czy podglądanie DOM.

W Cypressie developer nie musi pamiętać, aby pisać jawne oczekiwanie na zakończenie poleceń (wait znane z Selenium). Jest to zrobione za nas przez twórców frameworka - wszystko dzieje się automatycznie i kolejne polecenia oraz asercje wykonują się w odpowiednim momencie.

Kolejną z rzeczy wartych wspomnienia jest łatwość użycia i konfiguracji — jedno polecenie instaluje framework, a kolejne uruchamia dashboard, którym posługiwanie się jest intuicyjne.

Dashboard Cypress Rys. 1. Dashboard Cypress

Rozpoczynanie pracy

W kwestii wymagań, Cypress nie potrzebuje wiele: wystarczy Node.js oraz ulubione IDE. Aby umożliwić rozpoczęcie pracy, wystarczy wykonać następujące polecenia w katalogu projektu:

  1. npm init, aby stworzyć projekt node’owy
  2. npm install cypress --save-dev dla instalacji Cypressa

Po zakończeniu instalacji powstanie domyślna struktura:

Struktura Cypress Rys. 2. Struktura projektu Cypress

Objaśnienia:

  • fixtures - miejsce, gdzie możemy przechowywać gotowe zestaw danych, np. służące do zamockowania usług;
  • integration - lokalizacja testów;
  • plugins - miejsce do załączania zewnętrznych rozszerzeń dla Cypressa;
  • support - tutaj znajdą się np. stałe powtarzające się w wielu scenariuszach czy też nowe, customowe polecenia do globalnego reużycia.

Następnie przy pomocy komendy npx cypress open uruchamiamy dashboard i jeden z przykładowych testów.

Scenariusze testowe

W ramach tego wpisu, na warsztat weźmiemy stronę główną bloga Consdata Tech - https://blog.consdata.tech/ i stworzymy dla niej dwa przypadki testowe.

Pierwszy scenariusz będzie polegał na wejście na stronę, poczekaniu aż się załaduje i zweryfikowaniu kilku elementów, która potwierdzą nam, że portal jest w pełni działający.

Drugi scenariusz, nieco bardziej rozbudowany, dokona kilku interakcji z blogiem.

Pierwszy test

W katalogu integration tworzymy nowy plik o nazwie blog.spec.js, przechodzimy do jego edycji i uzupełniamy go o następującą treść:

describe('Blog Consdata Tech', () => {
    it('should check page fully loaded', () => {
        // ..
    });
})

Tak jak wcześniej wspomniałem, jeśli ktoś miał wcześniej styczność z testami w JS, wszystko będzie dla niego jasne.

Idąc od początku, describe nazywa nam całościowy kontekst, którego będą dotyczyć poszczególne scenariusze. it rozpoczyna konkretny przypadek testowy i to wewnątrz niego będziemy implementować właściwą logikę.

W tym momencie uruchamiamy dashboard Cypressa. Zobaczymy w nim, że pojawił się nasz plik. Po kliknięciu w niego uruchomi się przeglądarka oraz scenariusz testowy:

Cypress scenariusz testowy Rys. 3. Uruchomiony scenariusz w Cypress

Zostawmy przeglądarkę i dashboard włączony w tle - Cypress nasłuchuje na zmiany i od razu je wykonuje. Dzięki temu mamy ciągłą pętlę zwrotną z informacją czy to, co tworzymy przynosi oczekiwane efekty.

Wracając do tworzenia testu, jak wynika z nazwy should check page fully loaded, pierwszy z nich będzie sprawdzał czy strona, na którą wchodzimy poprawnie się załadowała. Dodajemy ciało do pustej metody:

cy.visit('https://blog.consdata.tech/').then(() =>{
    cy.get('.header-logo').should('be.visible');
    cy.get('footer').should('be.visible');
});

Jak widać, napisany kod jest właściwie samoopisujący się. W pierwszej linii odwiedzamy podany adres, następnie, gdy to się odbędzie, szukamy w DOM elementu o klasie header-logo i sprawdzamy czy jest widoczny. Operacje powtarzamy dla elementu footer. W przeglądarce uświadczy nas poniższy obrazek:

Dashboard Cypress Rys. 4. Scenariusz testowy zakończony powodzeniem

Interakcje

Twórcy Cypressa przygotowali zestaw metod, który ułatwi nam wykonywanie operacji na stronie. W skład tych poleceń wchodzi m.in. click(), type(), select() czy check().

Jeszcze zanim przejdziemy do implementacji drugiego scenariusza, trzeba zauważyć, że każdy z nich będzie zaczynał się od tej samej akcji - otworzenia strony. Możemy wynieść ten kawałek kodu do metody beforeEach(), która jest uruchamiana przed każdym testem:

beforeEach(() => {
    cy.visit('https://blog.consdata.tech/')
})

W ten sposób będziemy zgodni z regułą DRY :)

Wracając do właściwego testu, rzućmy na niego okiem:

it('search for a specific post', () => {
       const searchBoxElementId = '#search-box';

       cy.get(searchBoxElementId).should('be.not.visible'); // weryfikacja czy element nie jest widoczny
       cy.get('.desktop-navbar .search-icon').click(); // kliknięcie w ikonę wyszukiwarki
       cy.get(searchBoxElementId).should('be.visible'); // element powinien się pojawić
       cy.get(searchBoxElementId).type('ansible'); // wpisanie wartości
       cy.get(searchBoxElementId).type('{enter}').then(() => { // symulacja wciśnięcia przycisku enter, aby wysłać formularz
           cy.get('.post-title').should('contain', 'Ansible - jak uporządkować chaos?'); // weryfikacja oczekiwanego efektu
       })
   });

Podobnie jak poprzednio, idąc linijka po linijce, jesteśmy w stanie łatwo rozczytać, co się wydarzyło, nawet bez pomocy komentarzy.

Gdy zajrzymy do źródła strony w przeglądarce, okaże się, że w DOMie jest więcej elementów z klasą post-title, a mimo tego test przechodzi poprawnie. Jest to oczekiwane zachowanie - łańcuch komend get().should() znajduje wszystkie elementy i sprawdza czy w jakimkolwiek z nich znajduje się podana treść. Gdybyśmy chcieli sprawdzić czy pierwszy element zawiera konkretną wartość, możemy wykorzystać first():

  cy.first('.post-title').should('contain', 'Ansible - jak uporządkować chaos?');

Podsumowanie

Przystępność Cypressa (szczególnie dla web developerów, w związku z silnym zakorzenieniem w ekosystemie JavaScript) i minimum czasu potrzebnego na przygotowanie działającej konfiguracji mogą okazać się kluczowe dla osób szukających nietrudnego sposobu na automatyzację testów. Być może będzie to również okazja dla zrażonych do Selenium, by dać testom E2E drugą szansę.

Źródła

  • https://docs.cypress.io/
Najnowsze wpisy

  • Dostępność w PDF - dokumenty bez barier
  • Czy wiesz, że z pomocą @starting-style można animować elementy z display: none za pomocą samego CSS?
  • Czy wiesz, że w Angular 17 została wprowadzona alternatywa dla *ngSwitch?
Dołącz do nas

  • SENIOR FULLSTACK DEVELOPER (JAVA + ANGULAR) Poznań (hybrydowo) lub zdalnie UoP 14 900 - 20 590 PLN brutto
    B2B 19 680 - 27 220 PLN netto
  • REGULAR FULLSTACK DEVELOPER (JAVA + ANGULAR) Poznań (hybrydowo) lub zdalnie UoP 11 300 - 15 900 PLN brutto
    B2B 14 950 - 21 000 PLN netto
  • ZOBACZ WSZYSTKIE OGŁOSZENIA

newsletter

techniczny

Zapisz się

Podobne wpisy

post-image
WCAG

Dostępność w PDF - dokumenty bez barier

author
Kacper Hoffman 28 kwi 2025
post-image
angular

Czy wiesz, że z pomocą @starting-style można animować elementy z display: none za pomocą samego CSS?

author
Piotr Tatarski 7 kwi 2025
post-image
angular

Czy wiesz, że w Angular 17 została wprowadzona alternatywa dla *ngSwitch?

author
Dorian Mejer 10 mar 2025
Dołącz do nas

  • SENIOR FULLSTACK DEVELOPER (JAVA + ANGULAR) Poznań (hybrydowo) lub zdalnie UoP 14 900 - 20 590 PLN brutto
    B2B 19 680 - 27 220 PLN netto
  • REGULAR FULLSTACK DEVELOPER (JAVA + ANGULAR) Poznań (hybrydowo) lub zdalnie UoP 11 300 - 15 900 PLN brutto
    B2B 14 950 - 21 000 PLN netto
  • ZOBACZ WSZYSTKIE OGŁOSZENIA

Zapisz się na

newsletter

techniczny

consdata.com
  • Kontakt

    • sales@consdata.com
    • +48 61 41 51 000

  • Biuro

    • K9Office
      Krysiewicza 9/14
      61-825 Poznań
      Polska

  • Rozwiązania

    • Eximee
    • Kouncil
  • Blog Dołącz do nas
Copyright © 2024 Consdata. All rights reserved. Privacy Policy & Cookies
Chcemy używać plików cookie oraz skryptów podmiotów trzecich do polepszania funkcjonowania tej strony Zgadzam się