Naucz się tworzyć testy akceptacyjne z promptów: zamieniaj każde zgłoszenie funkcji na 5–10 jasnych scenariuszy obejmujących ścieżkę szczęśliwą i przypadki brzegowe bez rozdmuchanych zestawów testów.

Prompty w stylu chatowym wydają się jasne, bo czyta się je jak rozmowę. Jednak często mieszczą w sobie wybory, reguły i wyjątki w kilku przyjaznych zdaniach. Luki wychodzą dopiero, gdy ktoś użyje funkcji w praktyce.
Większość promptów polega cicho na założeniach: kto może wykonać akcję, co liczy się jako „sukces” (zapisane, wysłane, opublikowane, opłacone), co się dzieje, gdy brakuje danych i co użytkownik powinien zobaczyć przy niepowodzeniu. Ukrywają też nieostre standardy typu „wystarczająco szybko” czy „wystarczająco bezpiecznie”.
Niejasności zwykle wychodzą późno jako bugi i prace naprawcze. Programista zbuduje to, co rozumie z promptu, reviewer zatwierdzi, bo wygląda dobrze, a potem użytkownicy napotkają dziwne przypadki: podwójne przesłania, strefy czasowe, częściowe dane czy niezgodności uprawnień. Poprawki później kosztują więcej, bo często dotykają kodu, tekstów interfejsu, a czasem modelu danych.
Jakość nie wymaga ogromnych zestawów testów. To zdolność do zaufania funkcji w normalnym użyciu i pod przewidywalnym obciążeniem. Mały zestaw dobrze dobranych scenariuszy daje to zaufanie bez setek testów.
Praktyczna definicja jakości dla funkcji zbudowanych z promptu:
Właśnie po to przekształca się prompt w scenariusze akceptacyjne: weź nieostre żądanie i zamień je na 5–10 kontroli, które ujawniają ukryte reguły wcześnie. Nie próbujesz testować wszystkiego — chcesz złapać te błędy, które rzeczywiście się pojawiają.
Jeśli budujesz z szybkiego promptu w narzędziu vibe‑coding takim jak Koder.ai, wynik może wyglądać na kompletny, a i tak pominąć reguły brzegowe. Zestaw zwarte scenariuszy zmusza do nazwania tych reguł, gdy zmiany są jeszcze tanie.
Scenariusz akceptacyjny to krótki, prosty opis działania użytkownika i rezultatu, który powinien zobaczyć.
Trzymaj się powierzchni: co użytkownik może zrobić i co produkt pokazuje lub zmienia. Unikaj wewnętrznych szczegółów jak tabele bazy, wywołania API, zadania w tle czy który framework jest używany. Te detale mogą mieć znaczenie później, ale czynią scenariusze kruche i trudniejsze do uzgodnienia.
Dobry scenariusz jest też niezależny. Powinien dać się łatwo uruchomić jutro na czystym środowisku, bez polegania na tym, że inny scenariusz został wcześniej uruchomiony. Jeśli scenariusz zależy od wcześniejszego stanu, powiedz to jasno w setupie (np. „użytkownik ma już aktywną subskrypcję”).
Wiele zespołów używa Given‑When‑Then, bo wymusza jasność bez zamieniania scenariuszy w pełną specyfikację.
Scenariusz jest zwykle „gotowy”, gdy ma jeden cel, jasny stan początkowy, konkretną akcję i widoczny rezultat. Powinien być binarny: każdy z zespołu może powiedzieć „pass” lub „fail” po jego uruchomieniu.
Przykład: „Given zalogowany użytkownik bez zapamiętanej metody płatności, when wybiera Pro i potwierdza płatność, then widzi komunikat o sukcesie i plan widoczny jako Pro na koncie.”
Jeśli budujesz w chat‑first builderze takim jak Koder.ai, stosuj tę samą zasadę: testuj zachowanie wygenerowanej aplikacji (to, czego doświadcza użytkownik), a nie to, jak platforma wyprodukowała kod.
Najlepszy format to ten, który ludzie będą pisać i czytać. Jeśli połowa zespołu używa długich narracji, a druga połowa pisze lakoniczne punkty, pojawią się luki, duplikaty i spory o sformułowania zamiast pracy nad jakością.
Given‑When‑Then działa dobrze, gdy funkcja jest interaktywna i stanowa. Prosta tabela sprawdza się, gdy masz reguły wejście‑wyjście i wiele podobnych przypadków.
Jeśli zespół jest podzielony, wybierz jeden format na 30 dni i dostosuj go potem. Jeśli reviewerzy ciągle pytają „co to znaczy sukces?”, zwykle znak, by przejść do Given‑When‑Then. Jeśli scenariusze stają się rozwlekłe, tabela będzie łatwiejsza do przejrzenia.
Cokolwiek wybierzesz, ustandaryzuj. Trzymaj te same nagłówki, ten sam czas i poziom szczegółu. Uzgodnij też, czego nie włączać: pixel‑perfect UI, implementację wewnętrzną i gadanie o bazie danych. Scenariusze powinny opisywać to, co widzi użytkownik i jakie gwarancje daje system.
Umieść scenariusze tam, gdzie praca już się odbywa i trzymaj je blisko funkcji.
Popularne opcje to przechowywanie ich obok kodu produktu, w ticketach w sekcji „Acceptance scenarios” lub w współdzielonym dokumencie z jedną stroną na funkcję. Jeśli używasz Koder.ai, możesz też trzymać scenariusze w trybie Planowania, żeby zostały z historią budowy wraz z snapshotami i punktami rollbacku.
Kluczowe jest, żeby były przeszukiwalne, jedno źródło prawdy i wymóg scenariuszy przed uznaniem, że development się zaczyna.
Zacznij od przepisania promptu jako celu użytkownika plus jasnej linii mety. Użyj jednego zdania dla celu (kto chce czego), potem 2–4 kryteriów sukcesu, które możesz zweryfikować bez kłótni. Jeśli nie możesz wskazać widocznego rezultatu, to jeszcze nie masz testu.
Następnie rozbierz prompt na wejścia, wyjścia i reguły. Wejścia to to, co podaje lub wybiera użytkownik. Wyjścia to to, co system pokazuje, zapisuje, wysyła lub blokuje. Reguły to „tylko jeśli” i „musi” ukryte między wierszami.
Potem sprawdź, od czego zależy działanie funkcji. Tu kryją się luki scenariuszowe: wymagane dane, role użytkowników, uprawnienia, integracje i stany systemu. Przykładowo, jeśli budujesz aplikację w Koder.ai, określ, czy użytkownik musi być zalogowany, mieć utworzony projekt lub spełniać warunki planu, zanim akcja będzie możliwa.
Teraz napisz najmniejszy zestaw scenariuszy, który udowodni, że funkcja działa: zwykle 1–2 ścieżki szczęśliwe, a potem 4–8 przypadków brzegowych. Każdy scenariusz skupiony na jednej przyczynie potencjalnego niepowodzenia.
Dobry wybór przypadków brzegowych to: brak lub nieprawidłowe wpisy, niezgodność uprawnień, konflikty stanu typu „już wysłane”, problemy z zależnościami zewnętrznymi jak timeouty i zachowanie przy odzyskiwaniu (czytelne błędy, bez częściowego zapisu).
Zakończ szybkim przeglądem „co może pójść nie tak?”. Szukaj cichych niepowodzeń, mylących komunikatów i miejsc, gdzie system mógłby stworzyć błędne dane.
Scenariusz ścieżki szczęśliwej to najkrótsza, najbardziej normalna droga, gdzie wszystko idzie dobrze. Jeśli zrobisz ją nudną umyślnie, stanie się solidną podstawą, która ułatwia wykrycie przypadków brzegowych później.
Nazwij domyślnego użytkownika i domyślne dane. Użyj realnej roli, nie „Użytkownik”: „zalogowany klient z potwierdzonym e‑mailem” lub „Admin z uprawnieniami do edycji rozliczeń”. Potem określ najmniejsze przykładowe dane: jeden projekt, jedna pozycja na liście, jedna zapamiętana metoda płatności. To utrzymuje scenariusze konkretne i redukuje ukryte założenia.
Napisz najkrótszą drogę do sukcesu jako pierwszą. Usuń kroki opcjonalne i alternatywne przepływy. Jeśli funkcja to „Utwórz zadanie”, ścieżka szczęśliwa nie powinna zawierać filtrowania, sortowania ani edycji po utworzeniu.
Prosty sposób, by utrzymać to zwarte, to potwierdzić cztery rzeczy:
Potem dodaj jeden wariant, który zmienia tylko jedną zmienną. Wybierz tę, która najczęściej się łamie później, np. „tytuł jest długi” lub „użytkownik nie ma istniejących elementów”, i zachowaj wszystko inne identyczne.
Przykład: jeśli prompt mówi „Dodaj toast 'Snapshot created' po zapisaniu snapshotu”, ścieżka szczęśliwa to: użytkownik klika Utwórz snapshot, widzi stan ładowania, otrzymuje „Snapshot created”, a snapshot pojawia się na liście z właściwym timestampem. Wariant jednego parametru to ten sam przebieg, ale z pustą nazwą i jasną regułą domyślnego nazewnictwa.
Przypadki brzegowe to miejsce, gdzie kryje się większość bugów, i nie potrzebujesz ogromnego zestawu, żeby je złapać. Dla każdego promptu funkcji wybierz mały zestaw, który odzwierciedla realne zachowania i tryby awarii.
Typowe kategorie do wyciągnięcia:
Nie każda funkcja potrzebuje każdej kategorii. Pole wyszukiwania bardziej dba o wejścia. Przepływ płatności bardziej o integracje i dane.
Wybierz przypadki brzegowe pasujące do ryzyka: duży koszt błędu (pieniądze, bezpieczeństwo, prywatność), wysoka częstotliwość, łatwo łamane przepływy, znane wcześniejsze błędy lub problemy trudne do wykrycia po fakcie.
Przykład: dla „zmiany planu subskrypcji” scenariusze, które często się opłacają, to wygaśnięcie sesji w trakcie checkoutu, podwójne kliknięcie „Potwierdź” i timeout dostawcy płatności, który pozostawia plan niezmieniony przy jednoczesnym pokazaniu jasnego komunikatu.
Przykładowy prompt funkcji (w prostym języku):
„Kiedy coś popsułem, chcę przywrócić aplikację do poprzedniego snapshotu, aby ostatnia działająca wersja znów była aktywna.”
Poniżej zwarty zestaw scenariuszy. Każdy jest krótki, ale precyzuje rezultat.
S1 [Wymagane] Przywróć do najnowszego snapshotu
Given jestem zalogowany i jestem właścicielem aplikacji
When wybieram „Rollback” i potwierdzam
Then aplikacja wdraża poprzedni snapshot, a status aplikacji pokazuje nową wersję jako aktywną
S2 [Wymagane] Przywróć do wybranego snapshotu
Given przeglądam listę snapshotów dla mojej aplikacji
When wybieram snapshot „A” i potwierdzam rollback
Then snapshot „A” staje się wersją aktywną i widzę, kiedy został utworzony
S3 [Wymagane] Brak dostępu (auth)
Given jestem zalogowany, ale nie mam dostępu do tej aplikacji
When próbuję wykonać rollback
Then widzę błąd dostępu i rollback nie rozpoczyna się
S4 [Wymagane] Snapshot nie znaleziony (walidacja)
Given ID snapshotu nie istnieje (albo został usunięty)
When próbuję do niego przywrócić
Then dostaję jasny komunikat „snapshot nie znaleziony”
S5 [Wymagane] Podwójne wysłanie (duplikaty)
Given klikam „Potwierdź rollback” dwa razy szybko
When wysłane zostaje drugie żądanie
Then tylko jeden rollback się uruchamia i widzę pojedynczy wynik
S6 [Wymagane] Błąd wdrożenia (awaria)
Given rollback się rozpoczął
When wdrożenie kończy się błędem
Then aktualna wersja pozostaje aktywna, a błąd jest pokazany
S7 [Opcjonalne] Timeout lub utrata połączenia
Given moje połączenie zrywa się w połowie rollbacku
When odświeżę stronę
Then widzę, czy rollback nadal trwa, czy się zakończył
S8 [Opcjonalne] Już na tym snapshocie
Given snapshot „A” jest już aktywny
When próbuję przywrócić do snapshotu „A”
Then informują mnie, że nic się nie zmieniło i żadne nowe wdrożenie nie startuje
Każdy scenariusz odpowiada na trzy pytania: kto to robi, co robi i co musi być prawdziwe po akcji.
Celem nie jest „przetestować wszystko”. Celem jest pokryć ryzyka, które zaszkodzą użytkownikom, bez tworzenia sterty scenariuszy, których nikt nie uruchamia.
Jedna praktyczna sztuczka to oznaczanie scenariuszy według sposobu ich użycia:
Ogranicz się do jednego scenariusza na odrębne ryzyko. Jeśli dwa scenariusze zawodzą z tego samego powodu, prawdopodobnie potrzebujesz tylko jednego. „Nieprawidłowy format e‑mail” i „brak e‑maila” to różne ryzyka. Ale „brak e‑maila w Kroku 1” i „brak e‑maila w Kroku 2” mogą być tym samym ryzykiem, jeśli reguła jest identyczna.
Unikaj też powielania kroków UI w wielu scenariuszach. Trzymaj powtarzające się części krótkie i skup się na tym, co się zmienia. To jeszcze ważniejsze przy budowie w chat‑based narzędziu jak Koder.ai, bo UI może się przesuwać, gdy reguła biznesowa pozostaje ta sama.
Wreszcie, zdecyduj, co sprawdzać teraz, a co później. Część kontroli lepiej robić ręcznie na początku, a potem automatyzować, gdy funkcja się ustabilizuje:
Scenariusz powinien chronić przed niespodziankami, nie opisywać, jak zespół planuje zbudować funkcję.
Najczęstszy błąd to zamienienie celu użytkownika w checklistę techniczną. Jeśli scenariusz mówi „API zwraca 200” albo „tabela X ma kolumnę Y”, wiąże cię to z jednym rozwiązaniem i wciąż nie dowodzi, że użytkownik dostał to, czego potrzebował.
Innym problemem jest łączenie wielu celów w jeden długi scenariusz. Wygląda jak pełna podróż, ale gdy zawiedzie, nikt nie wie dlaczego. Jeden scenariusz powinien odpowiadać na jedno pytanie.
Uważaj też na przypadki brzegowe, które brzmią sprytnie, ale nie są realistyczne. „Użytkownik ma 10 milionów projektów” czy „sieć pada co 2 sekundy” rzadko odpowiadają produkcji i są trudne do odtworzenia. Wybieraj przypadki, które możesz przygotować w kilka minut.
Unikaj też niejasnych wyników typu „działa”, „bez błędów” czy „zakończono pomyślnie”. Te słowa ukrywają dokładny rezultat, który trzeba zweryfikować.
Jeśli budujesz funkcję eksportu źródeł jak w Koder.ai, słaby scenariusz to: „Gdy użytkownik kliknie eksport, system zipuje repo i zwraca 200.” Testuje to implementację, nie obietnicę.
Lepszy scenariusz: „Given projekt z dwoma snapshotami, when użytkownik eksportuje, then pobrany plik zawiera kod bieżącego snapshotu, a log eksportu zapisuje kto i kiedy eksportował.”
Nie zapomnij ścieżek „nie”: „Given użytkownik bez uprawnienia do eksportu, when próbuje eksportować, then opcja jest ukryta lub zablokowana i nie tworzy się żaden rekord eksportu.” Jedna linia może ochronić zarówno bezpieczeństwo, jak i integralność danych.
Przed uznaniem zestawu za „gotowy”, przeczytaj go jak wybredny użytkownik i jak administrator bazy. Jeśli nie potrafisz powiedzieć, co musi być prawdą przed testem, albo co znaczy „sukces”, to nie jest gotowe.
Dobry zestaw jest mały, ale konkretny. Powinieneś móc przekazać go komuś, kto nie pisał funkcji, i otrzymać te same wyniki.
Użyj tego szybkiego przeglądu by zatwierdzić (albo odesłać) scenariusze:
Jeśli generujesz scenariusze w chat‑based builderze jak Koder.ai, trzymaj ten sam standard: żadnego ogólnego „działa jak oczekiwano”. Żądaj obserwowalnych wyników i zapisanych zmian, a zatwierdzaj tylko to, co możesz zweryfikować.
Zrób ze scenariuszy realny krok procesu, nie sprzątanie na końcu.
Pisz scenariusze zanim zacznie się implementacja, gdy funkcję wciąż można tanio zmienić. Zmusza to zespół do odpowiedzi na niewygodne pytania wcześnie: co znaczy „sukces”, co się dzieje przy złym wejściu i czego jeszcze nie będziemy wspierać.
Używaj scenariuszy jako wspólnej definicji „done”. Product odpowiada za intent, QA za myślenie o ryzyku, engineering za wykonalność. Gdy wszyscy trzej czytają ten sam zestaw scenariuszy i zgadzają się, unikasz wysyłania czegoś „ukończonego”, ale nieakceptowalnego.
Workflow, który sprawdza się w większości zespołów:
Jeśli budujesz w Koder.ai, szkicowanie scenariuszy najpierw, a potem użycie Planning Mode może pomóc mapować każdy scenariusz na ekrany, reguły danych i widoczne dla użytkownika rezultaty zanim wygenerujesz lub edytujesz kod.
Dla ryzykownych zmian zrób snapshot przed iteracją. Jeśli nowy przypadek brzegowy złamie działający przepływ, rollback może uratować dzień rozplątywania efektów ubocznych.
Trzymaj scenariusze obok zgłoszenia funkcji (lub w tym samym tickecie) i traktuj je jak wersjonowane wymagania. Gdy prompt ewoluuje, zestaw scenariuszy powinien iść za nim, inaczej Twoje „gotowe” cicho się rozjedzie.
Zacznij od jednego zdania, które określa cel użytkownika i linię mety.
Następnie rozbij prompt na:
Z tego napisz 1–2 ścieżki szczęśliwe oraz 4–8 przypadków brzegowych odpowiadających realnym ryzykom (uprawnienia, duplikaty, timeouty, brak danych).
Bo prompt ukrywa założenia. Prompt może mówić „zapisz”, ale nie określać, czy to oznacza wersję roboczą czy opublikowaną, co się dzieje przy błędzie, ani kto ma do tego prawo.
Scenariusze zmuszają do wczesnego nazwania reguł, zanim wyślesz błędy takie jak podwójne przesłania, niezgodności uprawnień czy niespójne rezultaty.
Użyj Given–When–Then, gdy funkcja jest stanowa i interaktywna.
Użyj prostej tabeli wejście/wyjście, gdy masz dużo podobnych przypadków reguł.
Wybierz jeden format na miesiąc i go ustandaryzuj (ta sama forma czasowa, ten sam poziom szczegółu). Najlepszy format to taki, którego zespół naprawdę będzie używał.
Dobry scenariusz to:
Jest „gotowy”, gdy ktoś może go uruchomić i zgodzić się co do wyniku bez dyskusji.
Skoncentruj się na zachowaniu obserwowalnym:
Unikaj szczegółów implementacji: tabel bazy danych, kodów API, zadań w tle czy frameworków. Te detale się zmieniają i nie dowodzą, że użytkownik otrzymał oczekiwany rezultat.
Napisz najnudniejszą, normalną ścieżkę, gdzie wszystko idzie dobrze:
Potem potwierdź cztery rzeczy: właściwy ekran/stan, jasny komunikat sukcesu, dane zapisane i możliwość kontynuacji.
Wybieraj przypadki brzegowe według ryzyka i częstotliwości:
Celuj w , nie we wszystkie warianty.
Trzymaj to bezpiecznie i jasno:
Scenariusz błędu powinien udowodnić, że system nie psuje danych ani nie wprowadza użytkownika w błąd.
Traktuj output Koder.ai jak każdą inną aplikację: testuj to, co doświadcza użytkownik, nie to, jak kod został wygenerowany.
Praktyczne podejście:
Przechowuj je tam, gdzie już pracujecie i miejcie jedno źródło prawdy:
Jeśli używasz Koder.ai, trzymaj scenariusze w Planning Mode, żeby były powiązane z historią budowy. Najważniejsze: wymagaj scenariuszy zanim uznasz, że development się zaczyna.