PrzedsprzedażAkademia AI w testach i jakości oprogramowania: 1 350 zł zamiast 1 750 zł netto do 30 listopada

Startuje przedsprzedaż Akademii AI w testach i jakości oprogramowania: 5 tygodni z Tomaszem Stelmachem, start 11 stycznia 2027. Wyjątkowa cena 1 350 zł netto zamiast 1 750 zł tylko do 30 listopada.

zostało 38 dniZobacz program i zapisz się
Explicit Wait vs Implicit Wait w Selenium 4: kod z Duration i pomiar czasu
Czas czytania: 13 minut

Implicit Wait to globalne ustawienie sesji WebDrivera: każde wyszukanie elementu czeka na niego do podanego limitu. Explicit Wait to pętla w kodzie testu, która czeka na konkretny warunek, na przykład klikalność przycisku albo zniknięcie spinnera. Różnica explicit wait vs implicit wait sprowadza się więc do pytania: czekacie na element w ogóle, czy na stan, którego test naprawdę potrzebuje?

Ten tekst jest dla Was, jeśli piszecie testy w Selenium 4 w Javie i macie dość czerwonych buildów, które po ponownym uruchomieniu same robią się zielone. Wszystkie przykłady poniżej skompilowaliśmy i uruchomiliśmy 11.10.2026 na Selenium 4.51.0, JUnit 6.1.3 i Javie 25, z Chrome w trybie headless. Gdzie piszemy o czasach, podajemy wynik pomiaru, a nie wrażenie. Jeśli dopiero zaczynacie przygodę z tym narzędziem, najpierw przeczytajcie przewodnik Selenium: co to jest i od czego zacząć, a tu wróćcie, gdy pierwszy test zacznie losowo padać.

Explicit Wait vs Implicit Wait: czym się różnią?

Oba mechanizmy rozwiązują ten sam problem, czyli wyścig między testem a przeglądarką, ale robią to na innym poziomie. Implicit Wait działa po stronie sterownika i dotyczy tylko odnajdywania elementów. Explicit Wait działa po stronie Waszego kodu i może czekać na dowolny warunek, który da się wyrazić w Javie.

Kryterium Implicit Wait Explicit Wait Fluent Wait
Gdzie działa w sterowniku przeglądarki, dla całej sesji w kodzie testu, w jednym miejscu w kodzie testu, w jednym miejscu
Na co czeka aż element pojawi się w DOM na dowolny warunek: widoczność, klikalność, tekst, tytuł, alert jak Explicit Wait, plus własna lista ignorowanych wyjątków
Domyślna wartość 0 s (specyfikacja W3C WebDriver) brak, podajecie limit w konstruktorze brak, podajecie limit w withTimeout
Odpytywanie wewnątrz sterownika co 500 ms (domyślnie w Javie) tak często, jak ustawicie w pollingEvery
Składnia w Selenium 4 implicitlyWait(Duration.ofSeconds(5)) new WebDriverWait(driver, Duration.ofSeconds(10)) new FluentWait<>(driver).withTimeout(Duration.ofSeconds(10))
Kiedy wybrać małe skrypty, prototypy domyślnie w każdym frameworku elementy, które bywają przykryte albo przeładowywane

Źródło: dokumentacja Selenium „Waiting Strategies” i specyfikacja W3C WebDriver (szkic z 02.07.2026), sprawdzone 11.10.2026

Jedno sprostowanie, które często pada w starszych materiałach, także w poprzedniej wersji tego artykułu: Implicit Wait nie wydłuża testu, gdy element jest od razu na stronie. Dokumentacja Selenium mówi wprost, że sterownik zwraca element, gdy tylko go znajdzie. W naszym pomiarze findElement na istniejącym przycisku przy implicit wait 3 s trwał 12 ms. Implicit Wait działa też z findElements, tylko w mniej intuicyjny sposób, o czym za chwilę.

Dlaczego testy w Selenium potrzebują waitów?

Przeglądarka i test to dwa niezależne procesy. Polecenie driver.get() czeka na document.readyState równy „complete”, ale nowoczesne aplikacje doładowują dane już po tym momencie: tabela przychodzi z API, przycisk odblokowuje się po walidacji, spinner znika po sekundzie. Test, który kliknie za wcześnie, padnie, choć aplikacja działa poprawnie. Dokumentacja Selenium nazywa to wprost wyścigiem i jedną z głównych przyczyn niestabilnych testów.

Skala problemu z niestabilnymi testami

45%

naprawionych niestabilnych testów w badaniu Luo i in. dotyczyło czekania na operacje asynchroniczne (74 z 161 commitów)

1,5%

wszystkich uruchomień testów w Google kończy się wynikiem niestabilnym

16%

testów w Google ma jakiś poziom niestabilności

84%

przejść z zielonego na czerwony w CI Google dotyczy testu niestabilnego

Źródło: Luo, Hariri, Eloussi, Marinov, „An Empirical Analysis of Flaky Tests”, FSE 2014; Google Testing Blog, „Flaky Tests at Google and How We Mitigate Them”, 2016

Według badania Luo i współautorów z konferencji FSE 2014 kategoria „Async Wait” była największą grupą przyczyn: 74 ze 161 przeanalizowanych poprawek, czyli 45%. To samo badanie podaje, że 20 z 74 takich testów (27%) naprawiono, dokładając sleep, co tylko zmniejsza prawdopodobieństwo awarii, zamiast ją usunąć. Waity nie są więc kosmetyką, tylko lekarstwem na najczęstszą chorobę testów UI.

Google na swoim blogu testowym w 2016 roku podał, że około 1,5% wszystkich uruchomień testów daje wynik niestabilny, a prawie 16% testów ma jakiś poziom niestabilności. Te liczby dotyczą wszystkich testów, nie tylko Selenium, ale pokazują koszt: według tego samego wpisu 84% przejść z zielonego na czerwony w CI dotyczyło testu niestabilnego, więc ktoś musiał sprawdzić ręcznie, czy to błąd, czy szum. Szerzej o tym, gdzie automatyzacja zwraca się, a gdzie zaczyna kosztować, piszemy w tekście zalety i wady automatyzacji testów.

Jak działa Implicit Wait w Selenium 4?

Implicit Wait ustawiacie raz, zwykle zaraz po utworzeniu sterownika. Od Selenium 4, wydanego 13.10.2021 według bloga projektu, jedyną poprawną sygnaturą jest wersja z java.time.Duration. Stara wersja z TimeUnit została oznaczona jako przestarzała, a new WebDriverWait(driver, 30) z liczbą sekund nie skompiluje się w aktualnym Selenium. Poniżej zestawienie, które warto mieć pod ręką przy migracji starego frameworka.

// Selenium 3, dziś nie skompiluje się albo jest oznaczone jako przestarzałe driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); WebDriverWait wait = new WebDriverWait(driver, 30); new FluentWait<>(driver).withTimeout(15, TimeUnit.SECONDS); System.setProperty("webdriver.chrome.driver", "chromedriver.exe"); // Selenium 4 driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10)); WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30)); new FluentWait<>(driver).withTimeout(Duration.ofSeconds(15)); WebDriver driver = new ChromeDriver(); // Selenium Manager pobiera sterownik

Zwróćcie uwagę na ostatnią linię. Od Selenium 4.6, ogłoszonego na blogu projektu 04.11.2022, sterownik przeglądarki pobiera i dopasowuje Selenium Manager, więc System.setProperty("webdriver.chrome.driver", ...) jest zbędne, a ręcznie podana ścieżka potrafi wręcz przypiąć Was do starej wersji chromedrivera po aktualizacji Chrome. Na stacji, na której przygotowaliśmy przykłady, Selenium Manager sam pobrał sterownik dla Chrome 154.

Wszystkie testy w tym artykule korzystają z tej samej klasy bazowej i strony testowej waity.html: spinner znika po 1,5 s, przycisk „Zamów” odblokowuje się po 1,5 s, a potwierdzenie zamówienia pojawia się 2 s po kliknięciu. Zależności Maven i szkielet klasy wyglądają tak:

<dependencies> <dependency> <groupId>org.seleniumhq.selenium</groupId> <artifactId>selenium-java</artifactId> <version>4.51.0</version> </dependency> <dependency> <groupId>org.junit.jupiter</groupId> <artifactId>junit-jupiter</artifactId> <version>6.1.3</version> <scope>test</scope> </dependency> </dependencies>
import org.junit.jupiter.api.*; import org.openqa.selenium.*; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.chrome.ChromeOptions; import org.openqa.selenium.support.ui.*; import java.nio.file.Path; import java.time.Duration; import java.util.List; import static org.junit.jupiter.api.Assertions.*; class WaityTest { private WebDriver driver; private final String strona = Path.of("src/test/resources/waity.html").toUri().toString(); @BeforeEach void start() { ChromeOptions opcje = new ChromeOptions(); opcje.addArguments("--headless=new"); driver = new ChromeDriver(opcje); // Selenium Manager sam dobiera chromedriver driver.get(strona); } @AfterEach void stop() { driver.quit(); } }

Sam Implicit Wait to jedna linijka. Zwróćcie uwagę, że do kliknięcia i tak użyliśmy Explicit Wait, bo Implicit Wait czeka na obecność elementu w DOM, a nie na to, że da się go kliknąć. Przycisk „Zamów” istnieje od początku, tylko jest zablokowany i przykryty spinnerem.

@Test void implicitWait() { driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5)); new WebDriverWait(driver, Duration.ofSeconds(5)) .until(ExpectedConditions.elementToBeClickable(By.id("zamow"))).click(); WebElement potwierdzenie = driver.findElement(By.id("potwierdzenie")); assertEquals("Zamówienie nr 1042 przyjęte", potwierdzenie.getText()); }

Specyfikacja W3C WebDriver ustawia domyślny implicit wait na 0, limit ładowania strony na 300 000 ms, a limit skryptu na 30 000 ms. Ten sam dokument pokazuje, że implicit wait działa nie tylko przy szukaniu elementów, ale też przy czekaniu, aż pole będzie edytowalne w komendach clear i sendKeys. To kolejny powód, dla którego globalny timeout potrafi zaskoczyć w miejscu, w którym nikt go nie szukał.

Pułapka, którą zmierzyliśmy

findElements z ustawionym implicit wait nie zwraca pustej listy od razu. Sterownik czeka cały limit, licząc, że coś się jeszcze pojawi. W naszym pomiarze z 11.10.2026 sprawdzenie „czy elementu na pewno nie ma” przy implicit wait 3 s trwało 3 111 ms, podczas gdy znalezienie istniejącego elementu zajęło 12 ms. Test, który dziesięć razy sprawdza nieobecność komunikatu o błędzie, płaci za to pół minuty. Tak, Selenium też potrafi być bardzo cierpliwy, kiedy najmniej tego chcecie.

Jak napisać Explicit Wait z WebDriverWait i Duration?

Explicit Wait tworzycie w miejscu, w którym test potrzebuje konkretnego stanu aplikacji. Klasa WebDriverWait przyjmuje sterownik i limit typu Duration, a metoda until powtarza warunek, aż zwróci on wartość różną od null i false albo skończy się czas. Domyślnie wyjątek NoSuchElementException jest w trakcie czekania ignorowany, więc nie musicie go łapać sami.

@Test void explicitWait() { WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10)); wait.until(ExpectedConditions.invisibilityOfElementLocated(By.id("spinner"))); wait.until(ExpectedConditions.elementToBeClickable(By.id("zamow"))).click(); WebElement potwierdzenie = wait.until( ExpectedConditions.visibilityOfElementLocated(By.id("potwierdzenie"))); assertTrue(potwierdzenie.getText().contains("1042")); }

Ten test czeka na trzy różne rzeczy: zniknięcie spinnera, klikalność przycisku i widoczność potwierdzenia. Gotowe warunki z klasy ExpectedConditions, które najczęściej widzimy w naszych projektach, to:

  • elementToBeClickable przed kliknięciem, bo sprawdza widoczność i to, że element jest włączony
  • visibilityOfElementLocated przed odczytem tekstu albo asercją na treści
  • invisibilityOfElementLocated dla spinnerów, nakładek i toastów, które przykrywają stronę
  • textToBePresentInElementLocated, gdy element istnieje od razu, a zmienia się tylko jego treść
  • urlContains i titleIs po przekierowaniu, zanim zaczniecie szukać elementów nowej strony
  • frameToBeAvailableAndSwitchToIt i alertIsPresent dla ramek i okien dialogowych

Dokumentacja Selenium pokazuje dziś warunek częściej jako wyrażenie lambda niż jako ExpectedConditions. To wygodne, gdy żaden gotowy warunek nie pasuje: lambda może zwrócić dowolny obiekt, a until odda go Wam jako wynik. Poniżej wariant, który czeka na tekst potwierdzenia i od razu go zwraca.

@Test void explicitWaitZLambda() { WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10)); wait.until(d -> d.findElement(By.id("zamow")).isEnabled()); driver.findElement(By.id("zamow")).click(); String tekst = wait.until(d -> { List<WebElement> el = d.findElements(By.id("potwierdzenie")); return el.isEmpty() ? null : el.get(0).getText(); }); assertEquals("Zamówienie nr 1042 przyjęte", tekst); }

W Javie domyślny interwał odpytywania WebDriverWait to 500 ms. Jeśli element pojawi się po 1,2 s, test pójdzie dalej najpóźniej po około 1,5 s, a nie po pełnym limicie. Właśnie dlatego limit Explicit Wait możecie ustawić hojnie, na przykład 10 s, bez spowalniania szczęśliwej ścieżki. Same asercje na wyniku oczekiwania opisujemy osobno w tekście o asercjach w testach automatycznych.

Kiedy użyć Fluent Wait?

Fluent Wait to ta sama pętla co Explicit Wait, tylko z pełną kontrolą nad konfiguracją. WebDriverWait jest zresztą podklasą FluentWait. Sięgajcie po niego, gdy potrzebujecie jednej z czterech rzeczy: innego interwału odpytywania, ignorowania dodatkowych wyjątków, własnego komunikatu przy przekroczeniu limitu albo czekania na coś, co nie jest sterownikiem.

@Test void fluentWait() { Wait<WebDriver> wait = new FluentWait<>(driver) .withTimeout(Duration.ofSeconds(10)) .pollingEvery(Duration.ofMillis(300)) .ignoring(NoSuchElementException.class) .ignoring(ElementClickInterceptedException.class) .withMessage("Przycisk Zamów nie dał się kliknąć w 10 s"); wait.until(d -> { d.findElement(By.id("zamow")).click(); return true; }); WebElement potwierdzenie = wait.until(d -> d.findElement(By.id("potwierdzenie"))); assertTrue(potwierdzenie.isDisplayed()); }

W tym przykładzie warunek sam próbuje kliknąć przycisk. Gdy spinner jeszcze przykrywa stronę, Chrome zgłasza ElementClickInterceptedException, Fluent Wait go ignoruje i ponawia próbę co 300 ms. Przy limicie 10 s i interwale 300 ms warunek zostanie sprawdzony maksymalnie około 34 razy. Komunikat z withMessage trafi do raportu z testów, więc osoba analizująca błąd od razu wie, na co test czekał.

Uwaga na ignorowanie wyjątków. Jeśli dopiszecie do listy StaleElementReferenceException, upewnijcie się, że warunek wyszukuje element od nowa w każdej iteracji, tak jak w przykładzie powyżej. Ignorowanie wyjątku przy elemencie zapamiętanym poza lambdą sprawi, że test będzie czekał do końca limitu na coś, co już nigdy nie wróci.

Co się dzieje, gdy zmieszacie Implicit Wait i Explicit Wait?

Dokumentacja Selenium ostrzega: nie mieszajcie Implicit Wait i Explicit Wait, bo czasy oczekiwania stają się nieprzewidywalne, i podaje przykład, w którym implicit 10 s i explicit 15 s mogą dać timeout po 20 s. Sprawdziliśmy to na Selenium 4.51.0 i Chrome 154 na elemencie, którego nie ma na stronie.

@Test void pomiarMieszaniaWaitow() { driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10)); WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(15)); long start = System.nanoTime(); assertThrows(TimeoutException.class, () -> wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("nie-ma-mnie")))); System.out.println("POMIAR implicit 10 s + explicit 15 s: " + (System.nanoTime() - start) / 1_000_000 + " ms"); }

Nasz pomiar z 11.10.2026, Selenium 4.51.0, Chrome 154 headless

20,7 s

trwał timeout przy implicit 10 s i explicit 15 s, zamiast oczekiwanych 15 s

3,1 s

trwało findElements bez wyniku przy implicit wait 3 s

12 ms

trwało findElement na istniejącym elemencie przy implicit wait 3 s

6 z 6

testów z tego artykułu przeszło na Javie 25 i JUnit 6.1.3

Źródło: dane własne Quality Island, klasa WaityTest uruchomiona lokalnie, Maven 3.9.12

Skąd 20,7 s? Explicit Wait co 500 ms wywołuje findElement. Każde takie wywołanie czeka 10 s wewnątrz sterownika, bo tak ustawiliście implicit wait. Pętla sprawdza swój limit tylko między wywołaniami, więc pierwsze sprawdzenie kończy się po 10 s, drugie po kolejnych 10 s, i dopiero wtedy Explicit Wait zauważa, że przekroczył 15 s. Przy innych wartościach wynik będzie inny, i dokładnie o tę nieprzewidywalność chodzi w ostrzeżeniu dokumentacji.

Który wait wybrać w Waszym projekcie?

Z naszego doświadczenia przy budowie frameworków automatyzacji wynika prosta zasada: implicit wait ustawiony na 0, Explicit Wait w każdym miejscu, w którym test czeka na stan aplikacji. Najlepiej schowany w obiektach stron, a nie rozsiany po testach. Jak to poukładać w Page Object, pokazujemy w artykule o wzorcach projektowych w Selenium WebDriver.

Domyślnie

Explicit Wait

WebDriverWait z limitem 10 s w obiekcie strony. Warunek dobrany do akcji: klikalność przed kliknięciem, widoczność przed odczytem.

Wyjątek

Fluent Wait

Gdy element bywa przykryty, przeładowywany albo potrzebujecie własnego komunikatu i interwału odpytywania.

Ostrożnie

Implicit Wait

Tylko w małym skrypcie bez Explicit Wait. W frameworku z waitami jawnymi zostawcie 0, czyli wartość domyślną.

Nigdy

Thread.sleep

Za krótki sypie testami, za długi spowalnia cały pakiet. Według badania z FSE 2014 to łatka, nie poprawka.

Czy Implicit Wait ma jeszcze sens? W skrypcie na pół godziny, który ma przeklikać formularz i zrobić zrzut ekranu, jak najbardziej. W pakiecie regresji, który codziennie uruchamia setki testów w CI, koszt pułapek opisanych wyżej rośnie z każdym testem. Strategię waitów warto zapisać w zasadach Waszego zespołu, żeby każda nowa osoba nie wymyślała jej od nowa.

Jak ograniczyć flaky testy poza samymi waitami?

Waity usuwają największą grupę przyczyn, ale nie wszystkie. W badaniu Luo i współautorów kolejne kategorie to współbieżność i zależność od kolejności testów. U naszych klientów najczęściej widzimy pięć źródeł niestabilności, które wyglądają jak problem z czekaniem, a nim nie są:

  • Kruche selektory. Test czeka poprawnie, ale na element znaleziony absolutną ścieżką XPath, która zmienia się przy każdej przebudowie layoutu. Jak pisać stabilne lokatory, opisujemy w tekście selektory w Selenium
  • Wspólne dane testowe. Dwa testy równolegle zmieniają tego samego użytkownika. Każdy test powinien tworzyć własne dane
  • Zależność od kolejności. Test przechodzi tylko po innym teście, który zostawił aplikację w odpowiednim stanie
  • Animacje i przejścia CSS. Element jest widoczny, ale jeszcze się przesuwa. Pomaga czekanie na zakończenie animacji albo jej wyłączenie w środowisku testowym
  • Środowisko. Zbyt słaby agent CI albo wspólna baza danych. Tu żaden wait nie pomoże, trzeba naprawić infrastrukturę

Więcej typowych błędów, od testów bez asercji po automatyzację wszystkiego przez UI, zebrała Strefa QA w tekście o najczęstszych antywzorcach w testowaniu. W projekcie dla Argos uporządkowanie automatyzacji i procesów QA skróciło regresję przed releasem z 5 dni do 10 godzin, a liczba błędów krytycznych na produkcji spadła o 46%, co opisujemy w case study Argos. Stabilne testy to warunek takiego wyniku, bo regresji, której nikt nie ufa, nikt też nie skróci.

Jeśli chcecie przećwiczyć waity, Page Object i uruchamianie testów w CI pod okiem trenera, zajrzyjcie na szkolenie Automatyzacja testów Selenium WebDriver. Osobom, które dopiero zaczynają pisać w Javie, polecamy wcześniej szkolenie Programowanie w języku Java dla testerów. Gdy problemem nie jest wiedza, tylko framework, który zespół odziedziczył, pomaga doradztwo w automatyzacji testów albo przejęcie budowy testów w ramach usługi automatyzacja testów UI.

Co zabrać z tego artykułu

01Implicit Wait czeka globalnie tylko na obecność elementu w DOM. Explicit Wait czeka lokalnie na dowolny warunek, który potrzebny jest testowi.

02W Selenium 4 wszystkie limity podajecie jako Duration. Składnia z TimeUnit i new WebDriverWait(driver, 30) to Selenium 3.

03Selenium Manager od wersji 4.6 sam pobiera sterownik, więc System.setProperty dla chromedrivera możecie usunąć.

04Nie mieszajcie waitów: w naszym pomiarze implicit 10 s i explicit 15 s dały timeout po 20,7 s.

05findElements przy ustawionym implicit wait czeka cały limit, zanim zwróci pustą listę.

06Fluent Wait wybierzcie, gdy potrzebujecie własnego interwału, ignorowanych wyjątków albo komunikatu w raporcie.

Źródło: dokumentacja Selenium 2026, pomiar Quality Island z 11.10.2026

Wasze testy Selenium padają losowo, a zespół traci zaufanie do automatyzacji? Pomożemy znaleźć przyczyny i ustabilizować framework.

Automatyzacja testów UI


Powiązane na blogu Quality Island

Pełna lista źródeł

👍 2

Co o tym sądzisz?

Dodaj komentarz

Bądź na bieżąco
Strefa QA, portal z eksperckimi artykułami o jakości oprogramowania
Bądź na bieżąco
Bezpieczne programowanie z AI
Bezpieczne programowanie z AI: tworzenie oprogramowania z asystentami kodu

1 690,00 zł

26.11.26, 17.12.26, 28.01.27, 04.03.27, 25.03.27
1 dzień
AI Act i RODO w firmie
AI Act i RODO w firmie: bezpieczne korzystanie ze sztucznej inteligencji

1 290,00 zł

24.11.26, 15.12.26, 26.01.27, 02.03.27, 30.03.27
1 dzień
Testy bezpieczeństwa dla początkujących
Testy bezpieczeństwa dla początkujących: OWASP Top 10 i pierwsze testy aplikacji webowych

1 000,00 zł

18.11.26, 09.12.26, 13.01.27, 03.02.27, 24.02.27, 17.03.27
1 dzień
Popularne artykuły
Język Gherkin: co to jest i jak go używać w testowaniu oprogramowania
Smoke test: co to jest, kiedy go uruchamiać i czym różni się od sanity testu
Jak zostać testerem oprogramowania: ścieżka krok po kroku bez dyplomu informatyka
Najnowsze artykuły
Testowanie migracji danych i systemów: co sprawdzić, zanim przełączycie produkcję
Metryki DORA psują się w erze AI: dlaczego szybkość wydawania przestaje być dowodem jakości
OWASP Top 10:2025 okiem testera: co sprawdzić w każdej z dziesięciu kategorii
Popularne kategorie