Regex w testach automatycznych - praktyczny przewodnik

Wyrażenie regularne szuka słów zaczynających się na "ar", po których następuje litera z zakresu b-c lub k-m, a kończących się na "a". Znaleziono "arka", "arca", "siarka".

Napisano przez

Juliusz Król

Opublikowano

14 paź 2026

Spis treści

Gdy formularz przyjmuje błędny adres e-mail, test UI nie rozpoznaje zmiennego komunikatu albo log zawiera setki podobnych identyfikatorów, zwykłe wyszukiwanie tekstu szybko przestaje wystarczać. Wyrażenie regularne pozwala opisać taki tekst za pomocą wzorca, a potem wykorzystać go w walidacji danych, skryptach i automatyzacji testów. Poniżej pokazuję składnię, praktyczne przykłady, sposób użycia w testach oraz ograniczenia, o których łatwo zapomnieć.

Wzorce tekstowe pomagają pisać stabilniejsze i bardziej precyzyjne testy

  • Składnia opiera się między innymi na klasach znaków, kwantyfikatorach, grupach i kotwicach.
  • Automatyzacja UI wykorzystuje regex do sprawdzania dynamicznych komunikatów, adresów URL i treści elementów.
  • Kotwice ^ i $ odróżniają dopasowanie całej wartości od znalezienia fragmentu tekstu.
  • Testy negatywne są równie ważne jak poprawne przykłady, bo ujawniają zbyt szerokie wzorce.
  • Wydajność i przenośność zależą od silnika regex oraz konstrukcji wzorca.

Jak działa wzorzec i z czego się składa

Regex nie opisuje jednego konkretnego tekstu, lecz zbiór tekstów spełniających określone reguły. Wzorzec `INV-\d{4}` pasuje do `INV-2026`, ale nie do `INV-26` ani `INV-ABCD`. Dzięki temu mogę sprawdzać strukturę danych bez wpisywania każdej możliwej wartości osobno.

Podstawowe znaki mają zwykle podobne znaczenie w JavaScript, Pythonie, Javie czy narzędziach opartych na PCRE. Różnice pojawiają się przy bardziej zaawansowanych funkcjach, dlatego przed przeniesieniem wzorca do innego języka sprawdzam dokumentację konkretnego silnika.

Element Znaczenie Przykład
\d Jedna cyfra \d{4} dopasuje cztery cyfry
\w Znak słowa, zwykle litera, cyfra lub podkreślenie \w+ znajdzie ciąg znaków
\s Biały znak, na przykład spacja lub tabulator \s+ dopasuje jedną lub więcej spacji
[A-Z] Jedna wielka litera z podanego zakresu [A-Z]{2} pasuje do kodu PL
[^0-9] Znak inny niż cyfra Przydatne przy wykrywaniu separatorów
. Dowolny znak, zwykle poza znakiem nowej linii ab. pasuje do abc i ab1
| Alternatywa, czyli logiczne „lub” GET|POST dopasuje jedną z metod

Kwantyfikatory określają liczbę powtórzeń

Kwantyfikator mówi, ile razy może wystąpić poprzedni znak, grupa albo klasa znaków. Najczęściej używam +, gdy element musi pojawić się przynajmniej raz, oraz ?, gdy jest opcjonalny.

Symbol Znaczenie Przykład
* Zero lub więcej powtórzeń a*
+ Jedno lub więcej powtórzeń \d+
? Zero lub jedno wystąpienie https? pasuje do HTTP i HTTPS
{n} Dokładnie n powtórzeń \d{4}
{n,m} Od n do m powtórzeń \d{2,4}

Domyślnie kwantyfikatory są zachłanne, czyli próbują dopasować możliwie długi fragment. Dodanie znaku zapytania zmienia zachowanie na zachłanne minimalnie, na przykład .*?. W testach używam tej konstrukcji ostrożnie, bo często lepszy efekt daje precyzyjna klasa znaków niż „dowolny tekst”.

Jak budować wzorce, które nie łapią zbyt dużo

Najczęstszy błąd polega na napisaniu wzorca, który przechodzi dla poprawnego przykładu, ale akceptuje też dane błędne. Samo \d+ znajdzie cyfry w środku zdania. Jeśli test ma sprawdzić, czy cała wartość jest numerem zamówienia, potrzebuję kotwic początku i końca.

^ORD-\d{6}$

W tym przypadku ciąg musi zaczynać się od `ORD-`, zawierać dokładnie sześć cyfr i kończyć się zaraz po nich. W zależności od silnika ^ i $ mogą działać także względem poszczególnych linii, gdy włączony jest tryb wieloliniowy. Dlatego przy walidacji całego pola sprawdzam, czy używany tryb nie zmienia znaczenia kotwic.

Grupy poprawiają czytelność i pozwalają odzyskać fragment

Nawiasy grupują elementy i pozwalają zastosować kwantyfikator do całego wyrażenia. Wzorzec (PL|DE)-\d{5} opisuje kod kraju oraz pięć cyfr. Jeśli nie potrzebuję później odczytywać dopasowanego fragmentu, stosuję grupę nieprzechwytującą (?:PL|DE), ponieważ jasno komunikuje jej rolę.

^(?:PL|DE)-\d{5}$

Grupy przechwytujące są przydatne wtedy, gdy po dopasowaniu chcę pobrać konkretną część, na przykład numer wersji z tekstu `release-3.14`. Nie używam ich jednak automatycznie w każdym miejscu. W rozbudowanych wzorcach niepotrzebne przechwytywanie utrudnia odczyt wyników i może zwiększać koszt dopasowania.

Przykłady praktycznych wzorców

Poniższe przykłady traktuję jako punkty wyjścia, a nie gotowe reguły dla każdej aplikacji. Walidacja numeru telefonu, adresu e-mail czy daty zależy od przyjętego formatu, dlatego test powinien dokumentować, co dokładnie uznajemy za poprawną wartość.

Cel Wzorzec Co sprawdza
Adres e-mail w prostym formacie ^[^\s@]+@[^\s@]+\.[^\s@]+$ Tekst przed i po znaku @ oraz kropkę w domenie
Data RRRR-MM-DD ^\d{4}-\d{2}-\d{2}$ Układ cyfr i separatorów, ale nie poprawność kalendarzową
Wersja semantyczna ^v\d+\.\d+\.\d+$ Format taki jak v2.10.1
Identyfikator użytkownika ^[a-z][a-z0-9_]{2,15}$ Małą literę na początku i długość od 3 do 16 znaków

Przy dacie regex sprawdza wyłącznie kształt tekstu. Wartość `2026-99-99` przejdzie taki test, choć nie istnieje w kalendarzu. To dobry przykład granicy tej techniki: wzorzec nie zastępuje logiki domenowej.

Jak wykorzystać regex w automatyzacji testów

W automatyzacji testów wzorce najlepiej sprawdzają się tam, gdzie tekst jest częściowo zmienny, ale jego struktura pozostaje stała. Może to być komunikat zawierający numer zgłoszenia, adres URL po przekierowaniu, nazwa pliku raportu albo status z identyfikatorem sesji.

Testy interfejsu z dynamicznym tekstem

W Playwright mogę przekazać obiekt RegExp do lokatora tekstowego lub asercji. Dzięki temu test nie zależy od konkretnego numeru zamówienia, ale nadal wymaga właściwej treści i formatu.

await expect(
  page.getByText(/Zamówienie nr ORD-\d{6} zostało utworzone/)
).toBeVisible();

Jeśli element jest interaktywny, preferuję lokator oparty na roli, etykiecie albo stabilnym atrybucie testowym. Regex powinien doprecyzować tekst, a nie zastępować dobry wybór elementu. Zbyt szeroki lokator typu .* może dopasować kilka elementów i sprawić, że test przestanie sygnalizować realny błąd.

Sprawdzanie adresu URL i komunikatów

Po zalogowaniu aplikacja może przekierować użytkownika do adresu z dynamicznym identyfikatorem. Zamiast porównywać cały URL jako stały tekst, sprawdzam jego niezmienną część oraz oczekiwany format parametru.

await expect(page).toHaveURL(
  /\/konto\/uzytkownik\/\d+\/ustawienia$/
);

Podobnie można zweryfikować komunikat z czasem wykonania operacji. W takim teście warto ograniczyć dopasowanie do konkretnego elementu, aby przypadkowy tekst w stopce lub ukrytym kontenerze nie dał fałszywie pozytywnego wyniku.

await expect(page.locator('[data-testid="status"]'))
  .toHaveText(/Raport wygenerowany w \d+ sekund/);

Testy API i danych wyjściowych

W testach API regex przydaje się do lekkiej kontroli identyfikatorów, tokenów technicznych i komunikatów logowanych przez usługę. Nie próbuję nim jednak sprawdzać całego JSON-a. Do struktury danych lepiej użyć asercji pól, schematu JSON albo walidatora typów, a wzorzec zostawić dla pojedynczych wartości tekstowych.

expect(response.body.orderId).toMatch(/^ORD-\d{6}$/);
expect(response.body.status).toMatch(/^(new|paid|cancelled)$/);

W Pythonie analogiczny test może korzystać z modułu re. Gdy wzorzec jest używany wielokrotnie, kompiluję go raz i przekazuję do kolejnych sprawdzeń. To poprawia czytelność, a przy większej liczbie operacji pozwala uniknąć powtarzania przygotowania tego samego wzorca.

import re

order_id = re.compile(r"^ORD-\d{6}$")

assert order_id.fullmatch("ORD-202601")
assert not order_id.fullmatch("ORD-26")

W Pythonie surowy łańcuch oznaczony prefiksem r ogranicza problem podwójnego zapisu ukośników. W JavaScript zapis wygląda inaczej, bo wzorzec często umieszcza się między ukośnikami, na przykład /^ORD-\d{6}$/. To drobny szczegół, który regularnie powoduje błędy przy kopiowaniu wzorców między językami.

Jak testować sam wzorzec i unikać fałszywych wyników

Regex powinien mieć własny zestaw przypadków testowych. W praktyce przygotowuję co najmniej trzy grupy danych: przykłady poprawne, przykłady błędne oraz przypadki graniczne. Sama informacja, że jeden poprawny tekst przeszedł, nie mówi jeszcze, czy wzorzec jest wystarczająco precyzyjny.

Grupa Przykład dla identyfikatora Cel
Poprawne usr_anna7 Potwierdzenie podstawowego scenariusza
Niepoprawne usr-anna7 Wykrycie niedozwolonego separatora
Granica długości 2, 3, 16 i 17 znaków Sprawdzenie limitów kwantyfikatora
Znaki narodowe żółw_1 Ustalenie zachowania dla Unicode
Puste dane Pusty ciąg lub sama spacja Ochrona przed przypadkowym dopasowaniem

W testach negatywnych często zaczynam od wartości, która różni się od poprawnej tylko jednym znakiem. Takie przypadki szybko pokazują, czy reguła wymaga kotwic, czy klasa znaków nie jest zbyt szeroka i czy opcjonalny fragment nie pozwala na pustą wartość.

Najczęstsze pułapki

  • Brak kotwic sprawia, że wzorzec może znaleźć poprawny fragment w niepoprawnym tekście.
  • Kropka bez ucieczki oznacza dowolny znak, a nie dosłowną kropkę. Do adresu lub wersji użyj \..
  • Mylenie \d z pełnym formatem liczby prowadzi do akceptowania cyfr w przypadkowych miejscach.
  • Założenie, że \w zawsze obejmuje polskie znaki może dać inny wynik w zależności od języka i trybu Unicode.
  • Zachłanne .* potrafi pochłonąć większy fragment niż zakładano i utrudnia diagnozę błędu.
  • Bezpośrednie wstawianie danych użytkownika do wzorca może zmienić jego znaczenie. Takie wartości trzeba odpowiednio escapować.

Osobno sprawdzam też wielkość liter, znaki nowej linii i kodowanie. Flaga i włącza dopasowanie bez rozróżniania wielkości liter, a m zmienia działanie kotwic dla wielu linii. Nie dodaję flag „na wszelki wypadek”, bo każda zmienia kontrakt testu.

Przeczytaj również: XPath text - Stabilne selektory w testach automatycznych

Wydajność i ryzyko złożonych wzorców

Wzorce zawierające wiele zagnieżdżonych, zachłannych fragmentów, na przykład (a+)+ lub kilka sąsiadujących konstrukcji .*, mogą działać bardzo wolno dla odpowiednio przygotowanych danych. W aplikacji dostępnej publicznie jest to także potencjalne ryzyko typu ReDoS, czyli blokowania procesu przez kosztowne dopasowanie.

W testach zaczynam od prostszych klas znaków i ograniczonych zakresów, na przykład [A-Z0-9]{1,32}, zamiast używać nieograniczonego .*. Jeżeli wzorzec ma analizować duże logi albo dane od użytkownika, sprawdzam jego zachowanie dla długiego wejścia i nietypowych sekwencji, nie tylko dla krótkich przykładów.

Kiedy regex nie jest najlepszym narzędziem

Ta technika jest świetna do rozpoznawania lokalnych reguł tekstu. Gorzej radzi sobie z danymi, które mają zagnieżdżoną strukturę, zależności między polami albo skomplikowaną logikę biznesową. Próba opisania całego HTML-a, JSON-a czy warunków faktury jednym wzorcem zwykle kończy się kodem trudnym do utrzymania.

Problem Lepsze rozwiązanie
Sprawdzenie pól w JSON-ie Asercje właściwości lub walidacja schematu
Obliczenie poprawności daty Parser daty i reguły kalendarzowe
Wybór elementu UI Rola, etykieta, stabilny identyfikator testowy
Analiza HTML-a Parser DOM zamiast wielkiego wzorca
Sprawdzenie zależności biznesowych Jawna logika w kodzie testu

Moja praktyczna zasada jest prosta: regex powinien sprawdzać kształt pojedynczej wartości, a nie udawać parsera całego dokumentu. Jeśli wzorzec wymaga długiego komentarza, kilku wyjątków i wielu negatywnych lookaheadów, najczęściej warto rozbić walidację na mniejsze, nazwane reguły.

Trzeba też pamiętać o przenośności. W JavaScript, Pythonie i innych środowiskach podstawowe konstrukcje są podobne, ale obsługa lookbehind, flag, grup nazwanych czy właściwości Unicode może się różnić. Przed użyciem zaawansowanej składni uruchamiam ten sam zestaw przypadków w docelowym silniku, a nie w przypadkowym testerze online.

Jak wdrożyć wzorce w projekcie bez utraty czytelności

Najpierw zapisuję regułę słownie, na przykład „ma zaczynać się od prefiksu, zawierać sześć cyfr i nie mieć dodatkowych znaków”. Dopiero potem tworzę wzorzec. Taka kolejność ogranicza pokusę kopiowania przypadkowej konstrukcji znalezionej w dokumentacji bez zrozumienia jej zakresu.

  1. Zdefiniuj kontrakt danych i zapisz, co jest dozwolone, a co odrzucane.
  2. Zbuduj najmniejszy wzorzec, który opisuje wymagany format.
  3. Dodaj kotwice, jeśli testujesz całą wartość, a nie fragment.
  4. Przygotuj przypadki pozytywne, negatywne i graniczne.
  5. Uruchom testy w docelowym języku i sprawdź różnice silnika.
  6. Opisz nietypowe fragmenty komentarzem lub nazwą stałej.

W kodzie testowym wolę przechowywać skomplikowany wzorzec w nazwanej stałej niż wpisywać go bezpośrednio w kilku asercjach. Nazwa ORDER_ID_PATTERN mówi więcej niż anonimowy ciąg znaków, a zmiana formatu odbywa się w jednym miejscu.

const ORDER_ID_PATTERN = /^ORD-\d{6}$/;

await expect(page.locator('[data-testid="order-id"]'))
  .toHaveText(ORDER_ID_PATTERN);

Warto też unikać nadmiernego uzależniania testów od tekstu widocznego dla użytkownika. Regex dobrze toleruje zmienny numer czy datę, ale nie rozwiąże problemu, gdy aplikacja zmieni język interfejsu. Stabilna semantyka elementu i osobny wzorzec dla zmiennej wartości dają zwykle trwalszy test niż dopasowywanie całego komunikatu.

Od prostego dopasowania do wiarygodnego testu

Największą wartość daje nie sam sprytny wzorzec, lecz jasny kontrakt i dobrze dobrane przypadki testowe. Krótka reguła z kotwicami, ograniczonymi kwantyfikatorami i kilkoma testami granicznymi będzie bardziej użyteczna niż efektowna konstrukcja, której nikt nie chce później zmieniać.

W automatyzacji używam regex przede wszystkim do danych częściowo zmiennych: identyfikatorów, wersji, URL-i i komunikatów. Gdy problem dotyczy struktury dokumentu, logiki biznesowej albo poprawności kalendarza, sięgam po parser lub zwykłe asercje. Taki podział odpowiedzialności sprawia, że testy są szybsze, czytelniejsze i znacznie łatwiejsze do diagnozowania.

FAQ - Najczęstsze pytania

Kotwice wymuszają dopasowanie od początku do końca tekstu. Dzięki nim wzorzec ^ORD-\d{6}$ nie znajdzie poprawnego fragmentu w dłuższym, niepoprawnym ciągu. Przy trybie wieloliniowym trzeba sprawdzić, czy kotwice nie działają względem poszczególnych linii.

Regex sprawdza się przy dynamicznych komunikatach, adresach URL, nazwach plików i statusach zawierających zmienne identyfikatory. W Playwright można użyć obiektu RegExp w lokatorze lub asercji, ale element nadal najlepiej wybierać po roli, etykiecie albo stabilnym atrybucie testowym.

Należy przygotować przypadki poprawne, niepoprawne i graniczne. Warto sprawdzić między innymi minimalną i maksymalną długość, pusty ciąg, niedozwolone separatory, znaki narodowe oraz wartości różniące się od poprawnej tylko jednym znakiem.

Regex powinien sprawdzać kształt pojedynczej wartości, a nie zastępować parsera dokumentu lub logikę biznesową. Do JSON-a lepsze są asercje pól albo walidacja schematu, do dat parser i reguły kalendarzowe, a do HTML-a parser DOM. Trzeba też uważać na różnice między silnikami regex i złożone wzorce podatne na problemy wydajnościowe.

Oceń artykuł

Ocena: 4.00 Liczba głosów: 1

Tagi:

wyrażenia regularne playwright walidacja asercje redos

Udostępnij artykuł

Juliusz Król

Juliusz Król

Nazywam się Juliusz Król i od 4 lat zajmuję się automatyzacją testów oraz zapewnieniem jakości oprogramowania. Moje zainteresowanie tymi tematami zrodziło się z potrzeby zrozumienia, jak technologia może wspierać procesy tworzenia oprogramowania i jak kluczowe jest zapewnienie jego wysokiej jakości. W swoich tekstach skupiam się na praktycznych rozwiązaniach, które pomagają innym w efektywnym wdrażaniu automatyzacji oraz w rozwiązywaniu problemów związanych z jakością. Dzięki mojemu doświadczeniu staram się przekazywać wiedzę w sposób przystępny i zrozumiały, porównując różne podejścia oraz analizując aktualne trendy w branży. Zawsze dbam o to, aby moje materiały były rzetelne, aktualne i pomocne dla czytelników, którzy pragną rozwijać swoje umiejętności w obszarze QA.

Napisz komentarz