Rozwój kierowany testami z AI
Prosisz agenta o helper do liczenia rabatów. Oddaje kod, który wygląda poprawnie, demo przechodzi, scalasz zmiany. Dwa dni później dział finansowy zgłasza, że zamówienia z wygasłymi kuponami wciąż dostają rabat — AI napisało implementację i testy razem, więc testy weryfikowały tylko zachowanie, które samo wcześniej zakodowało. Testy napisane po kodzie najczęściej dowodzą jedynie, że kod robi to, co robi kod.
Rozwój kierowany testami odwraca tę kolejność. Najpierw piszesz testy, potwierdzasz, że nie przechodzą z właściwego powodu, a potem pozwalasz AI implementować pod cel, którego nie da się oszukać. Pętla red-green-refactor to dokładnie taki ciasny, weryfikowalny cykl, w jakim agenci są dobrzy — a krok “potwierdź czerwony” jest tym, co powstrzymuje AI przed pisaniem testów, które przechodzą, niczego nie sprawdzając.
Co z tego wyniesiesz
Dział zatytułowany „Co z tego wyniesiesz”- Powtarzalną pętlę red-green-refactor, którą prowadzisz z agentem, zamiast wpisywać każdą linię
- Gotowe do wklejenia prompty, które przypinają AI do jednej fazy naraz (testy, potem kod, potem refaktoryzacja)
- Wariant pętli dla Cursor / Claude Code / Codex, włącznie z tym, jak pozwolić zestawowi testów działać bez nadzoru
- Tryby awaryjne, które po cichu psują TDD sterowane przez AI — i jak przyłapać AI na edytowaniu testów, by wymusić zielony wynik
Przepływ pracy
Dział zatytułowany „Przepływ pracy”Klasyczny cykl to “czerwony, zielony, refaktor”. Z agentem każda faza staje się osobną, wąską instrukcją. Dyscyplina, dzięki której to działa: nigdy nie pozwól, by ta sama tura napisała jednocześnie nieprzechodzący test i kod, który go zaspokaja.
-
Napisz testy (czerwony). Określ zachowanie i przypadki brzegowe oraz wyraźnie zabroń implementacji. Opisujesz kontrakt, a nie prosisz o funkcję.
-
Potwierdź niepowodzenie (czerwony). Niech agent uruchomi zestaw i pokaże ci niepowodzenia. To dowodzi, że testy celują w prawdziwe, niezaimplementowane zachowanie — a nie w literówkę w imporcie, która “nie przechodzi” z niewłaściwego powodu.
-
Implementuj do przejścia (zielony). Teraz daj jedną wąską instrukcję: spraw, by te testy przeszły, nie dotykaj plików testowych. Cel jest jednoznaczny i sprawdzalny maszynowo.
-
Iteruj i refaktoryzuj. Agent uruchamia zestaw, czyta niepowodzenia i poprawia, aż będzie zielono. Gdy jest zielono, poproś o przebieg refaktoryzacji — testy są teraz twoją siatką bezpieczeństwa.
Przykład z życia: reguła rabatu z prawdziwymi przypadkami brzegowymi
Dział zatytułowany „Przykład z życia: reguła rabatu z prawdziwymi przypadkami brzegowymi”Zacznij od celowo małego pierwszego podejścia, żeby zobaczyć pętlę, a potem od razu przejdź do przypadku w kształcie produkcyjnym — metoda serwisowa ze ścieżkami błędów i zamockowaną zależnością, a nie czysta funkcja w izolacji.
Faza 1 — tylko testy. Przypnij model do pisania testów i niczego więcej:
Faza 2 — potwierdź czerwony. Nie pomijaj tego. Plik testowy importujący moduł, który jeszcze nie istnieje, powinien zawieść już przy rozwiązywaniu importu; test, który tu przechodzi, to test niczego nie sprawdzający.
Faza 3 — implementuj do zielonego. Dopiero teraz autoryzujesz implementację i odgradzasz testy:
To ostatnie zdanie jest kluczowe. Bez niego agent, który utknie, często “naprawi” nieprzechodzącą asercję, zamiast poprawić kod.
Faza 4 — refaktoryzacja pod zielonym. Gdy zestaw przechodzi, masz kontrakt, który pozwala bezpiecznie przebudować kod:
Prowadzenie pętli w każdym narzędziu
Dział zatytułowany „Prowadzenie pętli w każdym narzędziu”Fazy są wszędzie identyczne; różni się to, jak każde narzędzie uruchamia zestaw i ile pętli test-napraw-przetestuj wykona bez nadzoru.
Użyj trybu Agent i pozwól mu samodzielnie uruchamiać testy. W Settings -> Cursor Settings -> Agents -> Auto-Run ustaw Auto-Run Mode na Run in Sandbox (na macOS/Linux), aby polecenia wykonywały się automatycznie w piaskownicy bez pytania — to ścieżka pracy bez nadzoru, którą zaleca Cursor. Następnie dodaj npx vitest (lub npm test) do Command Allowlist, by runner testów uruchamiał się natychmiast nawet poza piaskownicą. Unikaj trybu Run Everything w pętli bez nadzoru: własne wskazówki dotyczące bezpieczeństwa Cursor mówią, by nigdy go nie używać, ponieważ pomija on wszystkie zabezpieczenia. Trzymaj fazy jako osobne tury czatu — punkty kontrolne Cursor pozwalają cofnąć się do “czerwonego”, jeśli przebieg zielonej fazy pójdzie nie tak. Obserwuj widok diff: jeśli edycja z fazy zielonej dotyka pliku *.test.ts, odrzuć ją.
Prowadź go z REPL albo skryptuj bezgłowo. Interaktywnie wklejaj kolejno każdy prompt fazy i pozwól Claude uruchamiać npm test. Aby pętla sama się korygowała, dodaj hook PostToolUse (matcher Edit|Write) w .claude/settings.json, który po każdej edycji ponownie uruchamia zestaw, dzięki czemu Claude od razu widzi niepowodzenia:
{ "hooks": { "PostToolUse": [ { "matcher": "Edit|Write", "hooks": [{ "type": "command", "command": "npx vitest run --reporter=dot" }] } ] }}Dla jednorazowej fazy zielonej w CI lub w skrypcie uruchom go bezgłowo:
claude -p "Implement src/services/pricing.ts so the suite passes. Run 'npx vitest run' and iterate until green. Do not edit any *.test.ts file." --allowedTools "Read,Edit,Write,Bash"W TUI uruchom fazę zieloną z --full-auto (ustawia piaskownicę workspace-write i zatwierdzenia on-request), by Codex mógł uruchamiać polecenie testowe i iterować bez pytania na każdym kroku:
codex --full-auto "Implement src/services/pricing.ts to pass tests in src/services/pricing.test.ts. Run 'npx vitest run' and iterate until green. Don't touch the test files."Jeśli chcesz pytania tylko wtedy, gdy coś faktycznie zawiedzie, użyj zamiast tego codex --ask-for-approval on-failure. Do równoległych eksperymentów red/green — powiedzmy próbowania dwóch różnych implementacji wobec tych samych zablokowanych testów — uruchom każdy w osobnym worktree gita, by zestawy się nie kolidowały.