Przejdź do głównej zawartości

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.

  • 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

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.

  1. Napisz testy (czerwony). Określ zachowanie i przypadki brzegowe oraz wyraźnie zabroń implementacji. Opisujesz kontrakt, a nie prosisz o funkcję.

  2. 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.

  3. 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.

  4. 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:

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ą.