Asercja: co to jest i jak używać asercji w testach automatycznych (Selenium, JUnit, TestNG, pytest)

Czas czytania: około 12 minut

Test automatyczny, który otwiera stronę, klika „Kup teraz”, wypełnia formularz i kończy się zielono, może nie sprawdzać niczego. Jeśli po drodze nie ma ani jednego porównania wyniku z oczekiwaniem, przechodzi także wtedy, gdy koszyk pokazuje zero złotych, a płatność zwraca błąd. Tym porównaniem jest asercja i to ona, nie kliknięcia, zamienia skrypt w test. W tym tekście wyjaśniamy, czym jest asercja, jakie ma rodzaje, jak używać jej w Selenium z JUnit, TestNG, pytest i AssertJ, dlaczego asercje padają, choć aplikacja działa, i jak pisać takie, które mówią, co się zepsuło.

Asercja w trzech zdaniach

Asercja to instrukcja w teście, która porównuje wynik rzeczywisty z oczekiwanym i przerywa test albo oznacza go jako nieudany, gdy się nie zgadzają. Bez asercji test tylko wykonuje kroki i przechodzi niezależnie od tego, co pokazuje aplikacja. W Selenium asercje dostarcza framework testowy (JUnit, TestNG, pytest, NUnit) albo biblioteka (AssertJ, Hamcrest), a sprawdza się nimi tytuł, adres, tekst, widoczność, atrybuty i liczbę elementów na stronie.

Najczęściej używane asercje w Selenium i JUnit

Asercje najszybciej wchodzą w nawyk na własnym kodzie. Na szkoleniu Automatyzacja testów Selenium WebDriver ćwiczycie je w praktyce, pod okiem trenera z co najmniej 5 latami doświadczenia w projektach.

Zobaczcie program szkolenia

Czym jest asercja?

Asercja to warunek zapisany w kodzie testu, który musi być prawdziwy, żeby test przeszedł: porównuje wartość rzeczywistą (to, co zwróciła aplikacja) z wartością oczekiwaną (to, co powinna zwrócić według wymagań) i przy niezgodności zgłasza błąd z komunikatem.

W terminologii ISTQB źródłem wartości oczekiwanej jest wyrocznia testowa: wymagania, specyfikacja, poprzednia wersja systemu albo wiedza eksperta, a wynik oczekiwany to zachowanie przewidziane przez tę wyrocznię. Asercja jest miejscem, w którym ta wiedza trafia do kodu. Wszystko, co test robi wcześniej (otwarcie strony, wpisanie danych, kliknięcie), przygotowuje tylko grunt pod to jedno porównanie.

Słowo pochodzi z programowania: instrukcja assert w wielu językach sprawdza założenie, które programista uważa za zawsze prawdziwe, i zatrzymuje program, gdy nie jest. W testach automatycznych asercja robi to samo, tylko założeniem jest wymaganie biznesowe. Kliknięcia i wpisy w teście są jak pytanie, a asercja jak odpowiedź. Test bez asercji zadaje pytanie i wychodzi, nie czekając, co usłyszy.

Dlaczego test bez asercji niczego nie sprawdza?

Test bez asercji przechodzi zawsze, dopóki nie wystąpi wyjątek techniczny, więc mówi tylko, że strona się otworzyła i elementy dały się kliknąć; nie mówi nic o tym, czy aplikacja zrobiła to, co powinna, a to jedyne pytanie, na które test ma odpowiedzieć.

Typowy przykład z projektów: zestaw dwustu testów regresyjnych, wszystkie zielone od miesięcy, a na produkcji rabat nalicza się od złej kwoty. Testy klikały przez koszyk i płatność, ale żaden nie porównywał kwoty na podsumowaniu z wartością oczekiwaną. Taki zestaw daje fałszywe poczucie bezpieczeństwa droższe niż brak testów, bo nikt nie sprawdza ręcznie tego, co „jest zautomatyzowane”.

Dlatego przegląd zestawu testów zaczyna się od pytania, ile testów kończy się asercją na wyniku biznesowym, a ile na tym, że element istnieje. Test, który sprawdza tylko obecność przycisku „Zapłać”, nie sprawdza płatności. Jak zaprojektować, co ma być sprawdzone, opisujemy w tekście o technikach projektowania testów, a jak zapisać wynik oczekiwany w zgłoszeniu w tekście Jak poprawnie zgłosić błąd.

Asercje twarde i miękkie: czym się różnią i kiedy której użyć?

Asercja twarda przerywa test przy pierwszej niezgodności i oznacza go jako nieudany, a asercja miękka zapisuje niezgodność, pozwala wykonać dalsze kroki i zgłasza wszystkie zebrane błędy na końcu; twardej używa się tam, gdzie dalszy test nie ma sensu, miękkiej tam, gdzie chcecie zobaczyć wszystkie błędy na jednym ekranie w jednym przebiegu.

Kryterium Asercja twarda Asercja miękka
Zachowanie przy niezgodności przerywa test natychmiast, wyjątek, status nieudany zapisuje błąd, test biegnie dalej, zgłoszenie zbiorcze na końcu
Kiedy warunek wstępny dalszych kroków: zalogowano, przeniesiono na stronę zakupu, zamówienie istnieje sprawdzanie wielu pól jednego ekranu: etykiety, wartości, widoczność elementów formularza
Zaleta szybka informacja, brak pracy na uszkodzonym stanie pełna lista błędów z jednego przebiegu, mniej cykli napraw
Wada jeden błąd na przebieg; kolejne widać dopiero po naprawie pierwszego łatwo zapomnieć o wywołaniu podsumowania i wtedy błędy giną; test biegnie na złym stanie
JUnit 5 Assertions.assertEquals i pozostałe Assertions.assertAll z listą lambd
TestNG Assert.assertEquals SoftAssert z assertAll na końcu
pytest assert pytest-check albo własna lista błędów
AssertJ assertThat(…).isEqualTo(…) SoftAssertions z assertAll

Praktyczna reguła: pierwsza asercja w teście jest twarda i sprawdza, czy test w ogóle doszedł tam, gdzie ma sprawdzać (właściwa strona, właściwy stan). Dalsze, na szczegółach jednego ekranu, mogą być miękkie. Miękka asercja bez wywołania podsumowania na końcu jest gorsza niż brak asercji, bo wygląda jak sprawdzenie, a nic nie zgłasza.

Jakie są rodzaje asercji?

Asercje dzielą się według tego, co porównują: równość i nierówność wartości, prawdę i fałsz warunku, obecność i brak wartości (null), zgłoszenie wyjątku, zawartość kolekcji i tekstu, a w narzędziach do testów interfejsu także asercje ponawiane, które czekają, aż warunek stanie się prawdziwy.

Rodzaj Wywołanie Przykład Uwaga
Równość assertEquals(oczekiwane, rzeczywiste) kwota na podsumowaniu równa 180,00 kolejność argumentów: w JUnit i TestNG oczekiwane jest pierwsze, pomylenie myli komunikaty
Nierówność assertNotEquals nowy identyfikator zamówienia różny od poprzedniego rzadko potrzebna, często zastępowana konkretną wartością
Prawda i fałsz assertTrue, assertFalse element widoczny, przycisk włączony komunikat błędu bez treści: „expected true”, zawsze dodajcie opis
Obecność wartości assertNull, assertNotNull odpowiedź zawiera identyfikator w testach interfejsu rzadziej, częściej w testach API i jednostkowych
Wyjątek assertThrows niepoprawny kod rabatu zgłasza wyjątek walidacji sprawdza też typ i komunikat wyjątku
Kolekcje i tekst assertThat z AssertJ lub Hamcrest: contains, hasSize, startsWith, matches lista produktów ma 3 pozycje i zawiera „Szkolenie Selenium” czytelniejsze komunikaty niż assertTrue(lista.contains(x))
Ponawiane (web-first) expect(locator).toHaveText w Playwright, cy.should w Cypress tekst pojawi się w ciągu limitu czasu w Selenium trzeba połączyć oczekiwanie z asercją ręcznie

Dokumentacja: asercje w JUnit 5, asercje w TestNG, assert w pytest, AssertJ, Hamcrest, asercje w Playwright. Nazwy różnią się między frameworkami, mechanizm jest ten sam: porównanie i wyjątek przy niezgodności.

Asercje w Selenium: co sprawdzać na stronie

Co sprawdzać asercjami w testach Selenium?

W testach Selenium asercjami sprawdza się tytuł i adres strony, tekst elementu, widoczność i stan (włączony, zaznaczony), wartość atrybutu, liczbę elementów pasujących do lokatora oraz brak elementu, którego być nie powinno; najważniejsza asercja w teście dotyczy wyniku biznesowego, nie obecności przycisku.

Selenium 4 z JUnit 5, Java: asercje twarde i miękkie w jednym teście

@Test
void rabatNaliczaSieOdKwotyNetto() {
    driver.get("https://sklep.przyklad.pl/koszyk");
    new WebDriverWait(driver, Duration.ofSeconds(10))
        .until(ExpectedConditions.visibilityOfElementLocated(By.id("kod-rabatowy")))
        .sendKeys("WIOSNA10");
    driver.findElement(By.id("zastosuj")).click();

    // twarda: bez potwierdzenia rabatu dalsze sprawdzenia nie mają sensu
    WebElement komunikat = new WebDriverWait(driver, Duration.ofSeconds(10))
        .until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector(".alert-success")));
    assertEquals("Kod WIOSNA10 został zastosowany", komunikat.getText(), "komunikat po zastosowaniu kodu");

    // miękkie: wszystkie pola podsumowania w jednym przebiegu
    assertAll("podsumowanie koszyka",
        () -> assertEquals("200,00 zł", driver.findElement(By.id("suma-netto")).getText(), "suma netto"),
        () -> assertEquals("20,00 zł",  driver.findElement(By.id("rabat")).getText(), "kwota rabatu"),
        () -> assertEquals("180,00 zł", driver.findElement(By.id("do-zaplaty")).getText(), "do zapłaty"),
        () -> assertTrue(driver.findElement(By.id("zaplac")).isEnabled(), "przycisk Zapłać włączony")
    );
}

TestNG, ten sam pomysł z SoftAssert

SoftAssert miekka = new SoftAssert();
miekka.assertEquals(driver.findElement(By.id("suma-netto")).getText(), "200,00 zł", "suma netto");
miekka.assertEquals(driver.findElement(By.id("do-zaplaty")).getText(), "180,00 zł", "do zapłaty");
miekka.assertAll();   // bez tej linii błędy nigdy nie zostaną zgłoszone

Trzy rzeczy w tym przykładzie: każda asercja ma komunikat, który mówi, co sprawdzała; element jest najpierw oczekiwany, potem sprawdzany; asercja twarda otwiera, miękkie domykają. Lokatory po identyfikatorach zamiast po strukturze opisujemy w tekście o selektorach w Selenium, a to, jak w ogóle zacząć, w tekście Selenium: co to jest i od czego zacząć.

Asercje w JUnit 5, TestNG, pytest i AssertJ: czym się różnią?

JUnit 5 i TestNG mają wbudowane klasy asercji z asercjami miękkimi (assertAll, SoftAssert), pytest używa zwykłego słowa kluczowego assert z rozbudowanym komunikatem o różnicy, a AssertJ i Hamcrest dodają płynny zapis i czytelne komunikaty dla kolekcji i tekstu; różnią się składnią i kolejnością argumentów, nie zasadą działania.

Framework Język Zapis Miękkie Uwaga
JUnit 5 Java, Kotlin Assertions.assertEquals(oczekiwane, rzeczywiste, komunikat) assertAll oczekiwane pierwsze; assertThrows i assertTimeout wbudowane
TestNG Java Assert.assertEquals(rzeczywiste, oczekiwane, komunikat) SoftAssert plus assertAll rzeczywiste pierwsze, odwrotnie niż JUnit; łatwo pomylić przy migracji
pytest Python assert rzeczywiste == oczekiwane, komunikat pytest-check pytest sam pokazuje różnicę wartości w komunikacie, bez osobnych metod
AssertJ Java assertThat(rzeczywiste).isEqualTo(oczekiwane) SoftAssertions płynny zapis z podpowiedziami w edytorze, bogate asercje na kolekcjach i tekście
Hamcrest Java, Python assertThat(rzeczywiste, equalTo(oczekiwane)) brak, przez biblioteki dopasowania składane w wyrażenia, czytelne komunikaty
NUnit C# Assert.That(rzeczywiste, Is.EqualTo(oczekiwane)) Assert.Multiple model ograniczeń jak w AssertJ
unittest Python self.assertEqual(rzeczywiste, oczekiwane) subTest wbudowany w Pythona, bardziej rozwlekły niż pytest

Kolejność argumentów to najczęstsze źródło mylących komunikatów: JUnit oczekuje wartości oczekiwanej jako pierwszej, TestNG rzeczywistej. Pomyłka nie psuje wyniku testu, ale komunikat „oczekiwano 180,00, otrzymano 200,00″ będzie odwrócony i wyśle programistę w złą stronę. AssertJ omija problem, bo w zapisie płynnym zawsze zaczyna od wartości rzeczywistej. Podstawy Javy i Pythona potrzebne do tych frameworków uczymy na szkoleniach Java dla testerów i Python dla testerów.

Dlaczego asercja pada, choć aplikacja działa?

Asercja w teście interfejsu pada mimo działającej aplikacji najczęściej dlatego, że sprawdza element, zanim aplikacja skończyła go rysować lub ładować dane; rozwiązaniem jest jawne oczekiwanie na warunek przed asercją albo asercja ponawiana, nie stałe uśpienie i nie zwiększanie limitów.

  • Oczekiwanie przed asercją. W Selenium asercja nie czeka. Jeśli tekst komunikatu pojawia się po odpowiedzi serwera, sprawdzenie milisekundę po kliknięciu zobaczy pustkę. Przed asercją stoi WebDriverWait z warunkiem na tekst, widoczność albo obecność, opisany w tekście o waitach w Selenium WebDriver.
  • Asercje ponawiane. Playwright i Cypress łączą oczekiwanie z asercją: sprawdzenie „element ma tekst” ponawia się do limitu czasu. W Selenium ten sam efekt daje warunek ExpectedConditions.textToBePresentInElement użyty przed asercją.
  • Stan przejściowy. Element widoczny, ale z poprzednią wartością: koszyk pokazuje 200,00 przez ułamek sekundy, zanim przeliczy się na 180,00. Oczekiwanie na konkretną wartość, nie na widoczność.
  • Dane testowe. Asercja oczekuje „180,00 zł”, a cena produktu zmieniła się w bazie testowej. Wartość oczekiwana liczona z danych wejściowych albo przygotowana przez API przed testem, nie wpisana na sztywno z zeszłego miesiąca.
  • Format. „180,00 zł” a „180.00 PLN”, spacja niełamliwa, białe znaki na końcu. Porównanie po normalizacji albo asercja na liczbie, nie na napisie.
450 000+
testów automatycznych napisanych przez zespół Quality Island, każdy z asercją na wyniku
5 dni na 10 h
skrócenie regresji u naszego klienta z e-commerce po przeniesieniu sprawdzeń logiki na testy API
46%
mniej błędów krytycznych na produkcji w tym samym projekcie
1
liczba asercji na wyniku biznesowym, poniżej której test nie jest testem

Liczby z projektu dla Argos, potwierdzone przez klienta. Część sprawdzeń, które wcześniej były asercjami w testach interfejsu, przeszła tam na poziom API, gdzie ta sama asercja na kwocie rabatu wykonuje się w milisekundy i nie zależy od rysowania ekranu.

Jak pisać dobre asercje?

Dobra asercja sprawdza jedną rzecz, ma komunikat mówiący, co sprawdzała i w jakim kontekście, porównuje z wartością oczekiwaną wyliczoną albo pobraną z wyroczni, a nie wpisaną z pamięci, stoi po oczekiwaniu na stan, nie przed nim, i dotyczy wyniku biznesowego, nie obecności elementu.

Jedna intencja
assertTrue(a && b && c) mówi tylko „coś nie tak”. Trzy asercje albo assertAll mówią, które z trzech
Komunikat z kontekstem
„do zapłaty po kodzie WIOSNA10″ zamiast pustego komunikatu. Przy padnięciu w pipeline to jedyne, co widać
Oczekiwane z wyroczni
Kwota po rabacie liczona z ceny i procentu w teście albo pobrana z API, nie „180,00″ wpisane na sztywno
Po stanie, nie po akcji
Oczekiwanie na warunek, potem asercja. Asercja tuż po kliknięciu sprawdza stan sprzed odpowiedzi serwera
Wynik, nie obecność
Obecność przycisku „Zapłać” nie dowodzi, że płatność działa. Asercja na potwierdzeniu zamówienia dowodzi
Bez logiki w asercji
Warunki i pętle wokół asercji ukrywają, co jest sprawdzane. Dane w tabeli parametrów, asercja prosta

Asercje to część architektury testów, obok Page Objectów i konfiguracji, o której piszemy w tekście Automatyzacja testów Selenium WebDriver: wzorce projektowe. Dobre miejsce na asercje to test, nie Page Object: klasa strony zwraca wartości, test je porównuje, dzięki czemu Page Object da się użyć w wielu testach z różnymi oczekiwaniami.

Ile asercji w jednym teście? Co najmniej jedna na wyniku biznesowym. Kilka asercji na jednym ekranie jest w porządku, jeśli sprawdzają jedną intencję testu, i wtedy warto sięgnąć po asercje miękkie; test, który sprawdza dziesięć niezwiązanych rzeczy, lepiej podzielić. Asercje trzymajcie w teście, nie w Page Objectach: klasa strony zwraca wartości, a test porównuje je z oczekiwaniami, dzięki czemu ta sama klasa służy wielu testom, a padnięcie widać w teście, nie w klasie pomocniczej.

Jakie są najczęstsze błędy w asercjach?

Najczęstsze błędy to test bez asercji, asercja tylko na obecności elementu, asercja przed oczekiwaniem na stan, miękka asercja bez podsumowania, kilka warunków w jednej asercji bez komunikatu, wartości oczekiwane wpisane na sztywno i asercje w Page Objectach.

  1. Zero asercji. Test klika i przechodzi. Sprawdźcie zestaw: ile testów kończy się porównaniem wyniku biznesowego.
  2. Tylko obecność. assertTrue(element.isDisplayed()) na przycisku „Zapłać” zamiast asercji na potwierdzeniu i kwocie.
  3. Asercja przed oczekiwaniem. Sprawdzenie tekstu milisekundę po kliknięciu. Test niestabilny, choć aplikacja działa.
  4. Miękka bez assertAll. SoftAssert bez wywołania podsumowania nigdy nie zgłosi błędu. Wygląda jak test, nie jest testem.
  5. Wiele warunków bez komunikatu. assertTrue(x == 1 && y.equals(“a”)) pada z „expected true”. Nikt nie wie, który warunek. Dlaczego tak się dzieje i jak działają && oraz ||, pokazujemy w lekcji operatory logiczne w Javie.
  6. Wartości na sztywno. „180,00 zł” wpisane w test przestaje być prawdą po zmianie ceny w danych testowych.
  7. Odwrócone argumenty. Oczekiwane i rzeczywiste zamienione miejscami. Test działa, komunikat kłamie.
  8. Asercje w Page Objectach. Klasa strony, która sama sprawdza wynik, nie nadaje się do testów z innymi oczekiwaniami.

Asercje poza Selenium: API i testy jednostkowe

Asercje działają tak samo w testach API i jednostkowych, a tam wykonują się szybciej i stabilniej niż w interfejsie; w testach API sprawdza się kod odpowiedzi, strukturę i wartości pól oraz czas, w testach jednostkowych wynik funkcji i zgłaszane wyjątki, a większość asercji na logice biznesowej powinna żyć właśnie na tych poziomach.

W Postmanie asercje pisze się w skryptach po żądaniu: kod odpowiedzi 200, pole „rabat” równe 20, czas poniżej 500 milisekund. Opisujemy to w tekstach o Postmanie i o testach integracyjnych i API w Postmanie. W testach jednostkowych asercja porównuje wynik funkcji naliczającej rabat z wartością oczekiwaną dla każdej klasy równoważności, bez przeglądarki i bez serwera. To tam piramida testów każe umieszczać sprawdzenia logiki, o czym piszemy w tekście o piramidzie testów.

Asercje, oczekiwania i budowę frameworka ćwiczymy na szkoleniu Automatyzacja testów Selenium WebDriver, a asercje w testach API na szkoleniu Wprowadzenie do testowania API Postman. Wiedzę dla liderów jakości publikujemy na portalu Strefa QA. Jeśli wolicie zacząć od kursu online, w przewodniku kursy Selenium WebDriver na Udemy porównujemy dziesięć kursów i podpowiadamy, po czym poznać, że kurs uczy aktualnego Selenium 4.

Co zabrać z tego artykułu

01Asercja zamienia skrypt w test. Bez porównania wyniku z oczekiwaniem test przechodzi także wtedy, gdy koszyk pokazuje zero złotych.

02Twarda otwiera test i sprawdza warunki wstępne, miękkie domykają szczegóły jednego ekranu. Miękka bez assertAll nie zgłasza niczego.

03Selenium nie ma własnych asercji. Dostarcza je JUnit, TestNG, pytest albo AssertJ, a różnią się składnią i kolejnością argumentów, nie zasadą.

04Asercja stoi po oczekiwaniu na stan, nie po kliknięciu. Większość „niestabilnych asercji” to asercje przed odpowiedzią serwera.

05Każda asercja ma komunikat z kontekstem i sprawdza jedną rzecz. Przy padnięciu w pipeline to jedyne, co widać.

06Asercje na logice biznesowej należą do testów API i jednostkowych. Przez interfejs sprawdzajcie wynik, który widzi użytkownik.

Wasze testy są zielone, a błędy i tak wychodzą na produkcji? Przejrzymy zestaw pod kątem tego, co naprawdę sprawdza: ile testów kończy się asercją na wyniku biznesowym, ile na obecności elementu, a ile na niczym. Oddamy listę do poprawy w kolejności od najgroźniejszej luki.

Porozmawiajmy o Waszych testach


Powiązane na blogu Quality Island

Pełna lista źródeł

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
Szkolenie AI Act w wyrobach medycznych: testy i dokumentacja AI pod MDR
AI Act w wyrobach medycznych
AI Act w wyrobach medycznych: testy i dokumentacja AI pod MDR

1690,00 PLN

30.11.26, 18.01.27, 08.03.27
1 dzień
Szkolenie AI Act w bankowości i ubezpieczeniach: scoring kredytowy, wycena ubezpieczeń i FRIA
AI Act w bankowości i ubezpieczeniach
AI Act w bankowości i ubezpieczeniach: scoring kredytowy, wycena ubezpieczeń i FRIA

1690,00 PLN

27.11.26, 15.01.27, 05.03.27
1 dzień
Szkolenie Testowanie systemów AI wysokiego ryzyka pod AI Act: dokumentacja testowa i QMS dla dostawców
Testowanie systemów AI wysokiego ryzyka pod AI Act
Testowanie systemów AI wysokiego ryzyka pod AI Act: dokumentacja testowa i QMS dla dostawców

2390,00 PLN

26.11.26, 14.01.27, 04.03.27
2 dni
Popularne artykuły
Język Gherkin: co to jest i jak go używać w testowaniu oprogramowania, grafika Quality Island
Język Gherkin: co to jest i jak go używać w testowaniu oprogramowania
Smoke test: co to jest i czym różni się od sanity testu, grafika Quality Island
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, grafika Quality Island
Jak zostać testerem oprogramowania: ścieżka krok po kroku bez dyplomu informatyka
Najnowsze artykuły
Agentic testing w pracy zespołu QA, co się zmienia w testowaniu z agentami AI
Agentic testing: czy Wasza praca właśnie się zmienia, czy znika
Ile kosztują testy oprogramowania, cennik i czynniki ceny, Quality Island
Ile kosztują testy oprogramowania: cennik i czynniki ceny
Strategia testowania w organizacji, strategia jakości na przykładzie case PKO BP, Quality Island
Strategia testowania w organizacji: czego uczy nas case PKO BP
Popularne kategorie