Test-driven development w Cursorze
Test-driven development w Cursorze polega na tym, że agent najpierw pisze czerwony zestaw testów, programista zatwierdza go jako specyfikację, a potem agent implementuje kod, aż testy przejdą, nie zmieniając ich. Kontrola niezmienności testów, testy mutacyjne i bramki CI dowodzą wyniku, więc przegląd skupia się na testach, a nie na każdej linii implementacji.
Potrzebujesz konwertera markdown-do-HTML dla swojego CMS-a. Zagnieżdżone listy, bloki kodu w cytatach i encje HTML sprawiają, że agent rzadko trafia we wszystkie przypadki za pierwszym razem, a pierwsza wersja agenta wygląda wiarygodnie. Czytanie 400 linii parsera w poszukiwaniu trzech błędnych gałęzi to dokładnie ta praca, której chcesz się pozbyć. Ta strona jest dla programistów, którzy na co dzień pracują z agentem Cursora, oraz dla tech leadów, którzy chcą, żeby ta sama pętla działała powtarzalnie w całym zespole.
Co daje pętla TDD w Cursorze
Dział zatytułowany „Co daje pętla TDD w Cursorze”- Dwa prompty, które czysto dzielą pracę: jeden pisze wyłącznie testy i zaślepkę, drugi implementuje bez prawa do ich zmiany.
- Sprawdzenie z dwóch poleceń (
git diffwzględem otagowanego commita „red” orazgit status), które dowodzi, że agent nie osłabił testów, żeby dojść do zielonego. - Krok testów mutacyjnych ze Strykerem, który pokazuje, czy zatwierdzone testy w ogóle potrafią złapać błąd.
- Prompt bramki przed PR (typy, lint, testy, progi pokrycia) oraz prompt zamieniający zgłoszenie błędu w test regresyjny.
- Sposoby wyjścia z pięciu typowych awarii tej pętli.
Zasadę stojącą za pętlą, niezależną od narzędzia, opisuje strona test-driven development ze wsparciem AI. Ta strona to procedura specyficzna dla Cursora.
Jak krok po kroku działa TDD z agentem Cursora?
Dział zatytułowany „Jak krok po kroku działa TDD z agentem Cursora?”Pętla ma jedną regułę, którą chroni cała reszta: testy są kontraktem i tylko ty zmieniasz kontrakt. Agent pisze pierwszą wersję testów, ty je przeglądasz i commitujesz, a od tej chwili agent pracuje wyłącznie nad implementacją.
-
Każ agentowi napisać testy i zaślepkę, nic więcej. Zaślepka rzucająca
Not implementedutrzymuje zestaw na czerwono z właściwego powodu i ustala sygnaturę funkcji, zanim powstanie jakakolwiek logika. -
Sam przejrzyj testy, a potem je zacommituj. Właśnie tu czytasz uważnie. Czytasz 40 krótkich asercji zamiast 400 linii parsera. Zacommituj je jako osobny commit „red” i otaguj go, żeby mieć stały punkt odniesienia.
-
Każ agentowi implementować do zielonego, z testami tylko do odczytu. Agent uruchamia zestaw w swoim terminalu, czyta błędy i iteruje.
-
Udowodnij, że testy nie zostały ruszone, a potem że są wystarczająco mocne. Uruchom kontrolę niezmienności testów i zawężony przebieg mutacyjny.
-
Uruchom bramkę przed PR i otwórz pull request. CI powtarza te same kontrole, więc nic nie zależy od twojej maszyny.
Zapisz specyfikację jako czerwone testy
Dział zatytułowany „Zapisz specyfikację jako czerwone testy”Otwórz agenta w nowym czacie i wklej poniższy prompt. Wskazuje Vitest i układ plików; zmień te dwa szczegóły pod swój projekt.
Teraz przeczytaj plik testów. Sprawdzasz trzy rzeczy: każde zachowanie, na którym ci zależy, ma dokładny oczekiwany string; oczekiwane stringi to naprawdę to, czego chcesz (agent mógł zakodować zgadywanie, z którym się nie zgadzasz); żaden test nie sprawdza czegoś, co gwarantuje już system typów. Popraw testy ręcznie albo poproś o zmiany. Gdy testy mówią dokładnie to, czego chcesz, zacommituj je i otaguj commit:
# Terminal, w katalogu głównym repozytoriumgit add src/lib/markdowngit commit -m "test: markdownToHtml specification (red)"git tag tdd-redTag tdd-red oznacza zatwierdzony kontrakt. Każda późniejsza kontrola porównuje z tagiem, a nie z HEAD, więc commit zrobiony po commicie „red” nie ukryje osłabionego testu.
Implementuj, aż zestaw przejdzie
Dział zatytułowany „Implementuj, aż zestaw przejdzie”Zacznij nowy czat, żeby implementacja nie opierała się na rozumowaniu, z którego powstały testy. Agent uruchamia npx vitest run w swoim terminalu przy każdej iteracji. To, czy Cursor pyta cię przed każdym poleceniem, zależy od trybu uruchamiania ustawionego w twoim workspace (dokumentacja Cursora, Agent security → Run modes, sprawdzone 2026-08-28). Jeśli twój tryb uruchamiania pozwala zatwierdzać konkretne polecenia, zatwierdź tylko polecenie testów, zamiast wyłączać zatwierdzanie dla wszystkiego.
Ograniczenie 6 jest ważniejsze, niż się wydaje. Bez warunku stopu agent łata pojedyncze przypadki, a parser obrasta gałęzią na każdy test. Skill /loop w Cursorze też potrafi powtarzać prompt aż do osiągnięcia wyniku (pojawił się w Cursorze 3.5, 2026-05-20); jeśli go używasz, zostaw w prompcie ten sam warunek stopu.
Udowodnij, że agent nie ruszył testów
Dział zatytułowany „Udowodnij, że agent nie ruszył testów”Nie ufaj podsumowaniu agenta, że zostawił testy w spokoju. Sprawdź to:
# Terminal: kończy się kodem 1 i wypisuje diff, jeśli śledzony plik testów różni się od otagowanego kontraktugit diff --exit-code tdd-red -- src/lib/markdown/__tests__/# Nie powinno nic wypisać: pokazuje nowe nieśledzone lub niezacommitowane pliki w katalogu testówgit status --porcelain src/lib/markdown/__tests__/git diff względem tagu łapie osłabiony test nawet wtedy, gdy został już zacommitowany, ale nie widzi nowych, nieśledzonych plików; git status --porcelain je widzi. Jeśli któreś z poleceń wypisze coś, czego nie zatwierdziłeś, odrzuć zmianę, przywróć testy przez git checkout tdd-red -- src/lib/markdown/__tests__/, usuń nowe pliki testów z listy i ponownie uruchom prompt implementacji. Gdy zatwierdzasz dodatkowe testy (testy mutantów albo test regresyjny opisane niżej), zacommituj je i przesuń tag poleceniem git tag -f tdd-red, żeby zatwierdzony zestaw stał się nowym kontraktem. Żeby reguła obowiązywała cały zespół, dodaj ją jako regułę projektu: „When asked to implement against existing tests, never modify files under __tests__/; report a suspected wrong test instead.” Reguła to instrukcja, nie ogrodzenie. Warstwą, która naprawdę egzekwuje zasadę, jest kontrola, której agent nie może edytować: hook Cursora, który sprawdza edycje ścieżek testów i odrzuca turę, albo zadanie CI porównujące diff testów z zatwierdzonym commitem. Oba wzorce pokazuje strona ochrona wyroczni.
Udowodnij, że testy potrafią złapać błąd
Dział zatytułowany „Udowodnij, że testy potrafią złapać błąd”Zielone testy, które zatwierdziłeś, są warte tyle, co ich asercje. Testy mutacyjne wprowadzają do implementacji drobne zmiany (odwracają porównanie, usuwają linię) i sprawdzają, czy przy każdej z nich pada co najmniej jeden test. Mutant, który przeżył, to błąd, który twój zestaw przepuściłby na produkcję.
# Terminal: Stryker 10.0.0 z runnerem Vitest (npm, sprawdzone 2026-09-26)npm install --save-dev @stryker-mutator/core @stryker-mutator/vitest-runnernpx stryker run --testRunner vitest --mutate src/lib/markdown/markdown-to-html.ts --incrementalZawęź --mutate do plików, które zmieniłeś; przebieg po całym repozytorium jest wolny i niewiele mówi o tej zmianie. --incremental zapisuje wyniki, więc kolejny przebieg testuje ponownie tylko zmieniony kod. Potem oddaj ocalałe mutanty agentowi:
Nowe testy trafiają do osobnego pliku, żebyś mógł przejrzeć je jako całość, zanim dołączą do zablokowanego zestawu: po zatwierdzeniu zacommituj plik i uruchom git tag -f tdd-red. Jak wysokiego wyniku wymagać, zanim pętla zacznie działać bez nadzoru, opisuje strona jak silna jest twoja wyrocznia.
Każde zgłoszenie błędu zamieniaj najpierw w czerwony test
Dział zatytułowany „Każde zgłoszenie błędu zamieniaj najpierw w czerwony test”Ten sam podział dotyczy poprawek błędów. Test regresyjny powstaje i zostaje potwierdzony na czerwono, zanim ktokolwiek zacznie szukać przyczyny, więc poprawka jest udowodniona i taka pozostaje.
Gdy zatwierdzisz test, zacommituj go, przesuń tag poleceniem git tag -f tdd-red i uruchom ponownie prompt implementacji do zielonego. Przy błędach sporadycznych i takich, których jeszcze nie umiesz odtworzyć, zacznij od procedury z debugowania w Cursorze.
Uruchom bramkę przed PR
Dział zatytułowany „Uruchom bramkę przed PR”Szybkie kontrole idą pierwsze, żeby błąd typów nie kosztował pełnego przebiegu pokrycia. Samo pokrycie linii to słaby sygnał, więc bramka ustawia też próg dla gałęzi.
Krok pokrycia wymaga zainstalowanego @vitest/coverage-v8 (5.0.2 w npm, sprawdzone 2026-09-26, zgodne z Vitest 5.0.2). Przebieg z pokryciem uruchamia też wszystkie testy, więc osobne zwykłe vitest run tylko by go powtórzyło. CI musi uruchamiać te same trzy polecenia; lokalny przebieg agenta to wygoda, a CI/CD z Cursorem pokazuje, jak wpiąć je w workflow.
Kto zatwierdza i co czyta?
Dział zatytułowany „Kto zatwierdza i co czyta?”Weryfikacja jest podzielona tak, żeby nikt nie czytał każdej linii implementacji i nikt nie musiał ufać raportowi samego agenta.
| Kontrola | Czego dowodzi | Kto za nią odpowiada |
|---|---|---|
| Przegląd pliku testów przed commitem „red” | Kontrakt mówi to, czego chcesz | Programista, który zlecił zmianę |
git diff --exit-code tdd-red i git status --porcelain na ścieżkach testów | Agent nie przepisał kontraktu | Programista lokalnie, CI w pull requeście |
| Wynik mutacyjny dla zmienionych plików | Kontrakt wykrywa błędną implementację | Programista; poprzeczkę ustala tech lead |
| Typy, lint, testy, progi pokrycia | Zmiana jest spójna z resztą kodu | CI, jako wymagany status check |
| Przegląd pull requesta | Zmiany w testach i publicznym API są zamierzone | Recenzent, który czyta najpierw testy; code review w Cursorze opisuje Bugbota jako drugiego czytelnika |
Recenzent czyta diff testów linia po linii, a diff implementacji tylko w wyjątkach: tam, gdzie ocalałe mutanty oznaczono jako równoważne, gdzie pokrycie jest poniżej progu i gdzie zmieniła się publiczna sygnatura.
Kiedy TDD z agentem Cursora to złe narzędzie?
Dział zatytułowany „Kiedy TDD z agentem Cursora to złe narzędzie?”| Działa dobrze | Działa słabo | Zamiast tego |
|---|---|---|
| Parsery, formatery, walidatory, reguły cenowe | Układ wizualny („czy to dobrze wygląda”) | Kontrole zrzutów ekranu lub w przeglądarce; zob. wzorce testowania w Cursorze |
| Handlery API z kontraktem żądania i odpowiedzi | Orkiestracja, w której przygotowanie przerasta kod | Testy integracyjne z prawdziwymi usługami |
| Poprawki błędów odtwarzalnych jednym wejściem | Optymalizacja wydajności | Benchmarki z budżetem; same testy poprawności przepuszczą wolny kod |
| Czyste transformacje danych | Kod legacy bez żadnych testów | Najpierw testy charakteryzacyjne, potem TDD dla zmiany |
Przy kodzie z bogatą przestrzenią wejść testy oparte na przykładach zachęcają agenta do dopasowania się do przykładów. Niezmienniki sprawdzane testami opartymi na właściwościach (na przykład z fast-check 4.10.2) trudniej obejść.
Dodaj skill TDD, żeby nie powtarzać promptu
Dział zatytułowany „Dodaj skill TDD, żeby nie powtarzać promptu”Jeśli uruchamiasz tę pętlę codziennie, dyscyplinę red-green-refactor może nieść skill zamiast wklejanego promptu. Skill tdd z repozytorium mattpocock/skills Matta Pococka to najczęściej instalowany skill TDD na skills.sh: 966 524 instalacje w migawce z 2026-09-26 (SECONDARY: odczyt z migawki wyszukiwarki, bo skills.sh nie był dostępny bezpośrednio).
# Terminal, katalog główny repozytorium: instaluje do .agents/skills/ dla Cursora (skills CLI 1.7.0)npx skills add mattpocock/skills --skill tdd -a cursorPotem poproś agenta: „Fix the rounding bug in invoice totals test-first.” Skill każe mu napisać czerwony test, uruchomić go, wprowadzić minimalną poprawkę, potwierdzić, że test przechodzi, i zrefaktoryzować. Skill to instrukcje od strony trzeciej, działające z twoimi uprawnieniami, więc przed instalacją przeczytaj jego SKILL.md (bezpieczeństwo skilli). Skill nie zastępuje opisanej wyżej kontroli niezmienności testów: mówi agentowi, jak ma się zachować, ale nie dowodzi, że tak się zachował. Więcej opcji, w tym test-driven-development z Superpowers, porównuje strona najczęściej instalowane skille praktyk inżynierskich.
Co się psuje, gdy agent Cursora prowadzi pętlę TDD?
Dział zatytułowany „Co się psuje, gdy agent Cursora prowadzi pętlę TDD?”Agent edytuje testy, żeby dojść do zielonego. To najgroźniejsza awaria, bo wynik wygląda na sukces. Objawy: mniejsza liczba testów, toBe poluzowane do toContain, dopisane .skip. Wyjście: łapie to kontrola git diff --exit-code; przywróć testy z tagu tdd-red, zacznij nowy czat i ponownie uruchom prompt implementacji. Jeśli to się powtarza, przenieś egzekwowanie z promptu do hooka albo kontroli w CI.
Agent robi przypadki specjalne pod wejścia z testów. Implementacja zawiera gałąź dopasowaną do dosłownego stringa z testu. Wychwytują to testy mutacyjne i przegląd kodu, a szybkim detektorem jest garść niewidzianych wejść: poproś agenta o dziesięć nowych próbek markdownu, niech przewidzi HTML, potem je uruchom. Wyjście: dodaj testy oparte na właściwościach albo odłożony zbiór przykładów (holdout), którego agent nigdy nie widzi.
Testy przechodzą dla dowolnej implementacji. Asercje w rodzaju toBeDefined() albo typeof result === 'string' nie mogą paść. Wyjście: prompt „najpierw testy” ich zabrania, a przebieg Strykera ujawnia mutanty, które przez nie przeżyły.
Testy są związane z wnętrzem implementacji. Testy szpiegujące prywatne funkcje pomocnicze pękają przy każdym refaktoringu i pchają agenta do zachowania złej struktury. Wyjście: przepisz je tak, żeby testowały tylko publiczną funkcję, i trzymaj zasadę „test public behaviour only” w regule projektu.
Pętla staje w miejscu. Liczba błędów przestaje spadać po trzech, czterech iteracjach, zwykle dlatego, że pozostałe testy ujawniają wadę projektu (parser linia po linii nie obsłuży zagnieżdżeń). Wyjście: zatrzymaj czat, przełącz się na Plan Mode i poproś o analizę padających testów oraz propozycję innego projektu, zanim powstanie kolejna linia kodu. Zatwierdź plan, a potem uruchom prompt implementacji w nowym czacie.
Dokąd dalej po TDD w Cursorze
Dział zatytułowany „Dokąd dalej po TDD w Cursorze”Pracujesz w Codeksie? Wersję tej pętli dla Codeksa opisuje strona testowanie z Codeksem.