Kiedy zacząć automatyzację
Automatyzacja nie zastępuje myślenia testera, tylko powtarza to, co tester wcześniej wymyślił. Dlatego warto zacząć od podstaw testów manualnych: technik testowych, przypadków testowych i zgłaszania defektów. Dobry przypadek testowy łatwo zamienić w test automatyczny, a zły zautomatyzowany jest po prostu szybciej wykonywanym złym testem.
To ostatnia część serii “Testowanie od podstaw”.
Wybór narzędzia
| narzędzie | język | zalety | na co uważać |
|---|---|---|---|
| Playwright | TypeScript, JavaScript, Python, Java, C# | automatyczne czekanie, szybki start, nagrywanie testów, wiele przeglądarek | młodsze od Selenium |
| Selenium | Java, Python, C#, JavaScript i inne | standard od lat, dużo ofert pracy i materiałów | czekanie trzeba obsłużyć samemu |
| Cypress | JavaScript, TypeScript | wygodne debugowanie w przeglądarce | ograniczenia przy wielu kartach i domenach |
Na start polecam Playwright z TypeScriptem: najszybciej da się w nim napisać stabilny test. Jeśli celujesz w konkretną firmę, sprawdź w ogłoszeniach, czego używa. Zasady, których nauczysz się w jednym narzędziu, przeniesiesz do każdego innego.
Pierwszy test w Playwright
Potrzebujesz Node.js. W pustym folderze uruchom:
npm init playwright@latest
Instalator zapyta o język i utworzy przykładowy projekt. Test wygląda tak:
import { test, expect } from "@playwright/test";
test("link Get started prowadzi do instalacji", async ({ page }) => {
await page.goto("https://playwright.dev/");
await page.getByRole("link", { name: "Get started" }).click();
await expect(page.getByRole("heading", { name: "Installation" })).toBeVisible();
});
Uruchom go poleceniem npx playwright test, a raport otworzysz przez npx playwright show-report. Przydatne jest też npx playwright codegen, które nagrywa Twoje kliknięcia jako kod. Traktuj nagrany kod jako szkic do poprawy, nie gotowy test.
Lokatory: jak wskazać element
Lokator mówi testowi, którego elementu dotyczy akcja. To od lokatorów najbardziej zależy, czy test przeżyje zmiany w aplikacji.
Od najlepszych do najgorszych:
- Rola i nazwa, czyli to, co widzi użytkownik i czytnik ekranu:
getByRole("button", { name: "Zapisz" }). - Etykieta pola:
getByLabel("E-mail"). - Atrybut testowy:
getByTestId("checkout-submit"), gdy programiści dodalidata-testid. - Tekst:
getByText("Zamówienie przyjęte"), dobry do sprawdzania komunikatów. - CSS i XPath: tylko gdy nic innego nie działa. Lokator typu
div > div:nth-child(3) > spanpsuje się przy każdej zmianie układu.
Jeśli w aplikacji brakuje dobrych lokatorów, poproś programistów o data-testid. To kilka minut ich pracy, a oszczędza godziny naprawiania testów.
Czekanie na elementy
Aplikacje webowe ładują dane w tle, więc element, którego szukasz, może pojawić się po chwili. Test, który nie poczeka, nie przejdzie, mimo że aplikacja działa. To najczęstsza przyczyna niestabilnych testów.
Najgorsze rozwiązanie: stała pauza. sleep(5000) sprawia, że test czeka 5 sekund zawsze. Gdy aplikacja odpowiada w pół sekundy, marnujesz czas. Gdy odpowiada w 6 sekund, test i tak nie przechodzi.
W Playwright czekanie jest wbudowane. Przed kliknięciem Playwright sam sprawdza, czy element jest widoczny, stabilny i aktywny, a asercje takie jak toBeVisible() ponawiają sprawdzenie aż do limitu czasu. W prostych testach nie musisz pisać żadnego czekania.
W Selenium czekanie obsługujesz sam. Są trzy rodzaje:
- implicit wait: globalny czas, przez jaki Selenium ponawia szukanie każdego elementu;
- explicit wait: czekanie na konkretny warunek konkretnego elementu;
- fluent wait: explicit wait z ustawianym interwałem sprawdzania i wyjątkami do pominięcia.
W praktyce najlepiej sprawdza się explicit wait:
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
wait.until(ExpectedConditions.elementToBeClickable(By.id("submit"))).click();
Nie mieszaj implicit i explicit wait w jednym projekcie. Dokumentacja Selenium ostrzega, że czasy oczekiwania stają się wtedy nieprzewidywalne.
Zasady dobrych testów automatycznych
- Testy niezależne od siebie. Każdy przygotowuje własne dane i nie zakłada, że inny test wykonał się wcześniej.
- Jeden test, jedno zachowanie. Łatwiej znaleźć przyczynę, gdy test nie przejdzie.
- Dane przez API, sprawdzenie przez interfejs. Konto testowe szybciej utworzysz żądaniem do API niż klikając formularz rejestracji.
- Czytelne nazwy. Nazwa testu w raporcie ma mówić, co nie działa, bez otwierania kodu.
- Najpierw najważniejsze ścieżki. Logowanie, zakup, płatność. Nie zaczynaj od strony “O nas”.
Gdy testów przybywa, pojawia się powtarzalny kod. Wtedy przydaje się wzorzec Page Object, czyli klasy z lokatorami i akcjami dla każdej strony. Przy pierwszych kilku testach to przesada.
Co dalej
Testy, które uruchamiasz tylko ręcznie, szybko się starzeją. Kolejny krok to uruchamianie ich automatycznie przy każdej zmianie w kodzie, o czym piszę w poradniku o regresji w CI. O strukturze większego projektu i zapisywaniu sesji logowania piszę w poradniku o automatyzacji regresji w Playwright.
Pytania o czekanie i lokatory regularnie padają na rozmowach, także na stanowiska manualne. Sprawdź się na pytaniach rekrutacyjnych w dziale o automatyzacji.
Seria “Testowanie od podstaw”
- Czym zajmuje się tester i jak zacząć
- Teoria testowania w pigułce
- Jak napisać przypadek testowy
- Jak zgłaszać defekty
- Testowanie API od podstaw
- Pierwsze kroki w automatyzacji testów (ten wpis)