Jedna funkcja może działać poprawnie w typowym scenariuszu, a mimo to zawodzić przy pustym polu, nietypowych danych albo powtórnym kliknięciu. Angielskie określenie test cases oznacza udokumentowane przypadki testowe, czyli konkretne instrukcje sprawdzania działania oprogramowania. Pokażę, jak je tworzyć, porządkować i wykorzystywać w zarządzaniu testami, aby dokumentacja pomagała wykrywać ryzyko, a nie tylko wypełniała repozytorium.
Dobra dokumentacja testów pokazuje nie tylko co sprawdzić, ale też dlaczego i z jakim skutkiem
- Przypadek testowy opisuje warunki, dane, kroki oraz oczekiwany rezultat.
- Najlepsze scenariusze obejmują ścieżki poprawne, błędne i wartości graniczne.
- Powiązanie z wymaganiem pozwala szybko ocenić, czego jeszcze nie zweryfikowano.
- Automatyzacja sprawdza się przede wszystkim przy testach powtarzalnych i stabilnych.
- Aktualizacja dokumentacji jest częścią testowania, a nie zadaniem odkładanym na koniec projektu.
Od wymagania do sprawdzalnego przypadku testowego
Przypadek testowy to opis pojedynczej próby, której celem jest potwierdzenie konkretnego zachowania systemu. W terminologii ISTQB obejmuje on między innymi dane wejściowe, warunki wykonania i oczekiwane wyniki. Dzięki temu druga osoba może powtórzyć test i dojść do porównywalnego wniosku.
Nie każdy opis błędu jest przypadkiem testowym. Zdanie „sprawdzić logowanie” mówi zbyt mało, bo nie określa konta, hasła, warunków początkowych ani tego, co dokładnie oznacza sukces. Dobrze napisany zapis ogranicza domysły i pozwala skupić się na zachowaniu aplikacji, a nie na interpretowaniu instrukcji.
| Element | Co powinien zawierać | Dlaczego ma znaczenie |
|---|---|---|
| Identyfikator i tytuł | Unikalne ID oraz krótki opis celu | Ułatwia wyszukiwanie i raportowanie |
| Warunki wstępne | Stan konta, środowiska, danych lub uprawnień | Zapobiega wykonywaniu testu w niewłaściwym stanie |
| Dane testowe | Wartości wejściowe, pliki, role i konfiguracje | Pozwala odtworzyć wynik |
| Kroki | Krótka sekwencja czynności | Pokazuje, jak przeprowadzić sprawdzenie |
| Oczekiwany rezultat | Obserwowalne zachowanie systemu | Umożliwia jednoznaczną ocenę zaliczenia |
| Priorytet i powiązanie | Ważność testu oraz wymaganie lub zadanie | Pomaga ustalić kolejność pracy i zakres regresji |
Przypadek, scenariusz i zestaw testów
Scenariusz testowy opisuje szerszy cel, na przykład „klient składa zamówienie z dostawą do paczkomatu”. Przypadki testowe rozbijają ten cel na konkretne warianty, takie jak poprawny adres, brak kodu pocztowego, niedostępny paczkomat czy próba zakupu produktu wycofanego ze sprzedaży.
Zestaw testów grupuje powiązane przypadki, a plan testów określa szersze ramy pracy, czyli zakres, środowisko, odpowiedzialności i terminy. To rozróżnienie jest praktyczne. Bez niego zespoły często próbują zarządzać pojedynczymi instrukcjami tak, jakby były całym planem jakości.
Jak projektować przypadki, które naprawdę wykrywają błędy
Najpierw zamieniam wymaganie na pytanie o zachowanie systemu. Dla funkcji zmiany hasła nie pytam tylko, czy formularz się otwiera. Sprawdzam również, co dzieje się po błędnym haśle, wygaśnięciu tokenu i użyciu hasła niespełniającego reguł bezpieczeństwa.
Przy projektowaniu warto przejść przez pięć prostych kroków:
- Określ cel i wskaż wymaganie, ryzyko lub regułę biznesową.
- Zdefiniuj warunki początkowe, na przykład rolę użytkownika, stan zamówienia albo wersję aplikacji.
- Dobierz dane normalne, błędne, puste i graniczne.
- Zapisz kroki tak, aby każdy prowadził do jednej obserwowalnej czynności.
- Opisz wynik językiem faktów, bez sformułowań typu „system powinien działać prawidłowo”.
Pozytywne i negatywne warianty
Test pozytywny sprawdza, czy poprawne dane prowadzą do oczekiwanego rezultatu. Wariant negatywny weryfikuje reakcję na błąd. Oba są potrzebne, ale w praktyce zespoły często poświęcają zbyt dużo uwagi szczęśliwej ścieżce, mimo że najdroższe problemy zwykle pojawiają się poza standardowym przebiegiem.
Dla formularza rejestracji warto uwzględnić między innymi poprawny adres e-mail, brak wymaganej wartości, zbyt krótkie hasło, zajęty adres oraz próbę wysłania formularza wielokrotnie. Każdy wariant powinien mieć własny oczekiwany rezultat, na przykład komunikat walidacyjny, zablokowanie przycisku albo utworzenie konta.
Wartości graniczne i klasy równoważności
Jeśli pole akceptuje od 1 do 99 sztuk produktu, nie ograniczam się do wartości 20. Sprawdzam 0, 1, 99 i 100, a także dane tekstowe i puste pole. To przykład analizy wartości granicznych. Z kolei klasy równoważności pozwalają podzielić dane na grupy, które system powinien obsługiwać w podobny sposób, dzięki czemu nie trzeba testować każdej możliwej wartości.
Nie chodzi o mechaniczne tworzenie setek przypadków. Lepiej mieć kilka dobrze dobranych wariantów, które pokrywają realne ryzyko, niż długą listę niemal identycznych instrukcji. W mojej ocenie szczególnie opłaca się testować granice tam, gdzie błąd może powodować utratę pieniędzy, danych albo uprawnień.
Jak zarządzać zestawem testów w zespole
Sama dokumentacja nie poprawi jakości, jeśli nikt nie wie, który przypadek jest aktualny, kto go wykonał i z jaką wersją systemu. Dlatego każdy przypadek powinien mieć status, właściciela, priorytet oraz historię wykonania. W małym projekcie wystarczy prosty arkusz, ale przy wielu wydaniach szybko potrzebne staje się dedykowane narzędzie z filtrowaniem i raportami.
Praktyczny cykl może wyglądać tak:
- Draft oznacza szkic wymagający przeglądu.
- Ready wskazuje przypadek gotowy do wykonania.
- Blocked informuje o przeszkodzie, na przykład niedostępnym środowisku.
- Passed i Failed opisują wynik konkretnego uruchomienia.
- Outdated oznacza zapis, który nie pasuje już do produktu.
Trzeba rozdzielić status przypadku od wyniku wykonania. Ten sam przypadek może przejść w wersji 2.4, a nie przejść w wersji 2.5 po zmianie reguły biznesowej. Nadpisywanie starego wyniku prowadzi do utraty kontekstu i utrudnia analizę regresji.
Śledzenie pokrycia wymagań
Powiązanie wymagania z testem nazywa się śledzeniem lub traceability. Najprostsza macierz pokazuje, które wymagania mają testy, które przypadki wykryły defekty oraz co trzeba ponownie sprawdzić po zmianie kodu. Nie traktuję jej jako biurokracji. Przy krytycznych funkcjach jest to szybki sposób na odpowiedź, czy zmiana została rzeczywiście zweryfikowana.
Priorytet warto ustalać według ryzyka, a nie długości opisu. Funkcja płatności, logowania i nadawania uprawnień zwykle zasługuje na najwyższą wagę, nawet jeśli jej test zajmuje tylko minutę. Z kolei rzadko używana funkcja pomocnicza może trafić do późniejszego cyklu, jeśli jej awaria nie zatrzyma procesu biznesowego.
Manualne, automatyczne i eksploracyjne sprawdzanie
Dokumentacja nie musi oznaczać, że każdy test będzie wykonywany ręcznie. Ten sam cel można sprawdzić przez instrukcję dla testera, skrypt automatyczny albo sesję eksploracyjną. Wybór zależy od częstotliwości powtórzeń, stabilności funkcji, kosztu utrzymania i tego, czy wynik da się jednoznacznie zmierzyć.
| Podejście | Najlepsze zastosowanie | Ograniczenie |
|---|---|---|
| Manualne | Nowe funkcje, interfejs, nietypowe ścieżki | Wynik zależy od uwagi i doświadczenia wykonującego |
| Automatyczne | Regresja, API, powtarzalne reguły i obliczenia | Skrypt wymaga utrzymania po zmianach produktu |
| Eksploracyjne | Odkrywanie nieznanych problemów i szybka ocena jakości | Trudniej je odtworzyć bez dobrych notatek |
Automatyzuję przede wszystkim przypadki stabilne, często wykonywane i ważne dla procesu. Jeśli funkcja zmienia się co kilka dni, pisanie rozbudowanego skryptu może przynieść mniejszą korzyść niż krótka sesja manualna. Dobra reguła praktyczna to ocena, czy test będzie powtarzany co najmniej kilka razy w każdym wydaniu i czy jego wynik jest wystarczająco przewidywalny.
Testy eksploracyjne nie są chaotycznym klikaniem. Nadaję im cel, czas, zakres i dane, a po sesji zapisuję obserwacje oraz znalezione ścieżki. Część odkryć zamieniam później w stałe przypadki, lecz nie próbuję dokumentować każdej czynności wykonanej podczas eksploracji.
Co najczęściej psuje dokumentację testową
Pierwszym problemem są kroki opisane zbyt ogólnie. „Zweryfikuj koszyk” nie mówi, jakie produkty dodać, jaki rabat zastosować ani czy sprawdzamy cenę, podatek, dostawę czy stan magazynowy. Drugi błąd to oczekiwany rezultat, którego nie da się zaobserwować, na przykład „system działa poprawnie”.
Najczęściej poprawiam te problemy w następujący sposób:
- dzielę zbyt długi przypadek na mniejsze, gdy ma kilka niezależnych celów,
- usuwam kroki zależne od wiedzy jednej osoby,
- dodaję konkretne dane i warunki początkowe,
- opisuję komunikaty, statusy, zmiany w bazie lub reakcje interfejsu,
- oznaczam przypadki przestarzałe zamiast zostawiać je bez komentarza.
Pułapką bywa również kopiowanie testów dla każdej przeglądarki, urządzenia i roli. Część kombinacji można pokryć macierzą konfiguracji, a część wybrać na podstawie udziału użytkowników i ryzyka. Większa liczba przypadków nie zawsze oznacza większą jakość, szczególnie gdy połowa z nich sprawdza dokładnie tę samą regułę.
Przeczytaj również: Testowanie komunikatów o błędach - Jak robić to dobrze?
Jak mierzyć skuteczność, a nie samą aktywność
Sam procent zaliczonych testów jest mylący. Wynik 95% może wyglądać dobrze, jeśli wykonano setki przypadków pomocniczych, ale pominięto krytyczny proces płatności. Patrzę również na pokrycie wymagań, liczbę defektów znalezionych po wydaniu, czas regresji, odsetek niestabilnych testów i liczbę przypadków bez właściciela.
Test niestabilny, czyli flaky test, raz przechodzi, a raz kończy się błędem bez zmiany kodu. Jeśli zespół ignoruje takie sygnały, raporty tracą wiarygodność. Lepiej oznaczyć problem, znaleźć przyczynę i naprawić test niż bez końca uruchamiać go ponownie, aż przypadkiem zakończy się wynikiem pozytywnym.
Jak zbudować użyteczny zestaw od pierwszego sprintu
Na początku projektu nie tworzę kompletnej encyklopedii wszystkich funkcji. Wybieram 10-20 najważniejszych przypadków związanych z główną ścieżką użytkownika, bezpieczeństwem, pieniędzmi i integracjami. Dopiero po pierwszym wykonaniu widać, które instrukcje są niejasne, których danych brakuje i gdzie produkt ma największe ryzyko.
Dobry zestaw startowy powinien zawierać przynajmniej jeden test poprawny, jeden negatywny i jeden graniczny dla każdej istotnej reguły. Do tego dochodzi identyfikator wymagania, priorytet, środowisko oraz jasny sposób oznaczania wyniku. Taki minimalny standard daje zespołowi wspólny język bez obciążania go nadmiarem formalności.
Dokumentację aktualizuję przy zmianie wymagania, a nie dopiero przed publikacją wersji. Jeśli przypadek nie jest już potrzebny, oznaczam go jako nieaktualny i zachowuję informację o przyczynie. Dzięki temu zestaw pozostaje krótszy, bardziej wiarygodny i faktycznie wspiera decyzję o wydaniu produktu.