Blog

Testy Selenium: jak pisać stabilne testy i kiedy zmienić narzędzie

Kategoria:

Selenium WebDriver steruje prawdziwą przeglądarką przez standard W3C i obsługuje testy end-to-end w Javie, Pythonie, C# i JavaScripcie. W 2026 roku w wielu firmach działa na nim kilkaset albo kilka tysięcy testów, a przepisanie ich od zera zajęłoby zespołowi miesiące. Ten tekst jest dla takich zespołów: jak utrzymać testy Selenium w dobrej formie i po czym poznać, że pora na migrację.

Dlaczego testy Selenium są niestabilne?

W zestawach Selenium, które przejmowałem, niestabilność wracała do tych samych przyczyn:

  • Stałe opóźnienia (Thread.sleep) zamiast czekania na konkretny stan strony. Na szybkim komputerze test przechodzi, na przeciążonym agencie CI już nie.
  • Kruche lokatory: długie ścieżki XPath albo klasy CSS generowane przez framework frontendowy, które zmieniają się przy kolejnym buildzie.
  • Zależności między testami. Test B zakłada dane zostawione przez test A, więc przy równoległym uruchomieniu kolejność się rozjeżdża i oba padają.
  • Współdzielone dane testowe. Dwa testy edytują to samo konto w tej samej sekundzie.

Jak pisać stabilne testy w Selenium?

Czekaj na stan strony

Zamiast Thread.sleep(3000) używam jawnych oczekiwań: WebDriverWait z warunkiem, na przykład widocznością elementu albo możliwością kliknięcia. Test czeka dokładnie tyle, ile potrzeba, i ani sekundy dłużej.

WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
WebElement zapisz = wait.until(
    ExpectedConditions.elementToBeClickable(By.cssSelector("[data-testid='zapisz']")));
zapisz.click();

Oczekiwań niejawnych (implicit wait) nie łączę z jawnymi. Dokumentacja Selenium ostrzega przed takim połączeniem, bo czasy oczekiwania potrafią się wtedy sumować w nieprzewidywalny sposób. Przykład kosztu: przy implicit wait ustawionym na 10 sekund każde sprawdzenie, że element zniknął ze strony, trwa pełne 10 sekund, zanim Selenium zwróci pustą listę.

Lokatory odporne na zmiany

Proszę developerów o atrybuty testowe, na przykład data-testid, na elementach, z których korzystają testy. To jedna linia w kodzie komponentu, a lokator przestaje zależeć od układu strony i stylów. Gdy atrybutów brakuje, wybieram kolejno: id, nazwę pola formularza, tekst widoczny dla użytkownika. Długa ścieżka XPath jest u mnie ostatnią opcją.

Page Object i jeden cel na test

Wzorzec Page Object zamyka lokatory i akcje danej strony w jednej klasie. Zmiana w formularzu logowania oznacza wtedy poprawkę w jednym miejscu zamiast w czterdziestu testach. Każdy test sprawdza jedną rzecz i sam przygotowuje swoje dane, przez API albo bezpośrednio w bazie, bez klikania przez interfejs. Unikalne dane na test, na przykład adres e-mail z sygnaturą czasu, rozwiązują problem współdzielonych kont.

Równoległość i Selenium Grid

Niezależne od siebie testy uruchamiam równolegle w Selenium Grid albo w kontenerach. Zestaw, który sekwencyjnie trwa godzinę, na ośmiu węzłach kończy się w kilkanaście minut, pod warunkiem że testy nie dzielą danych. Podobny mechanizm dla Playwrighta w Jenkinsie opisałem w tekście o dynamicznym shardingu testów.

Raport, który pozwala postawić diagnozę

Przy nieudanym teście zapisuję zrzut ekranu, kod HTML strony i logi konsoli przeglądarki. Bez tych trzech plików analiza porażki z nocnego przebiegu zaczyna się od próby odtworzenia jej ręcznie, co przy błędach zależnych od czasu kończy się zdaniem „u mnie działa”.

Selenium czy Selenide?

Selenide to biblioteka dla Javy zbudowana na Selenium, z wbudowanym czekaniem na elementy i zwięzłym API. W zespołach javowych z dużym zestawem Selenium przejście na Selenide bywa tańsze niż migracja na nowy framework, bo zespół przepisuje testy stopniowo, w tym samym języku i w tym samym repozytorium. Podstawy obu narzędzi opisałem we wprowadzeniu do Selenide i Selenium.

Kiedy zmienić Selenium na Playwright?

Migrację rekomenduję, gdy w projekcie zgadzają się co najmniej dwa punkty z tej listy:

  • naprawianie niestabilnych testów zajmuje zespołowi więcej czasu niż pisanie nowych,
  • aplikacja jest mocno dynamiczna (SPA w React albo Angularze) i oczekiwania trzeba dopisywać do większości akcji,
  • zespół pisze frontend w TypeScripcie i chce mieć testy w tym samym języku,
  • testy potrzebują przechwytywania ruchu sieciowego, atrap API i kilku kontekstów przeglądarki w jednym scenariuszu.

Porównanie obu narzędzi znajdziesz w tekście Selenium czy Playwright, a kolejne kroki przejścia w checkliście migracji z Selenium do Playwrighta. Migracje zestawów Selenium i Selenide zaczynam od audytu. Część testów da się usunąć, bo sprawdza to samo co testy API, a część przenieść na niższy poziom, o czym piszę w tekście o rodzajach testów automatycznych. Do przepisania zostaje wtedy mniejsza część zestawu.

Jak pomagam w QA Sensei

Od 20 lat pracuję w IT, od siedmiu jako inżynier jakości, a Selenium, Selenide i Playwright znam z projektów produkcyjnych. Jeśli Wasz zestaw Selenium częściej blokuje wydania, niż je zabezpiecza, w Bilansie Jakości oceniam, które testy naprawić, które przenieść na poziom API, a które usunąć, i czy migracja zwróci się w Waszym projekcie. Pracuję zdalnie w całej Polsce, a w okolicach Wrocławia także u klienta.