Przejdź do głównej zawartości

Wzorce testowania w Cursorze

Wzorce testowania w Cursorze to prompty i kontrole, dzięki którym agent Cursora pisze testy na podstawie opisanego zachowania, a nie kodu, który właśnie przeczytał. Obejmują istniejący i legacy kod, ścieżki błędów, błędy z produkcji, luki w pokryciu, dane testowe, testy w przeglądarce i niestabilne testy. Każdy wzorzec kończy się dowodem, że testy potrafią nie przejść.

Wdrożyłeś serwis płatności bez testów automatycznych. Prosisz agenta Cursora o zestaw testów: powstaje 30 testów, wszystkie zielone, pokrycie skacze do 85%. Dwa tygodnie później refaktor psuje zwroty i nic nie robi się czerwone, bo każda asercja powtarzała to, co kod już robił. Ta strona jest dla programisty, który pisze prompty, i dla tech leada, który decyduje, czego musi dowodzić pull request z testami.

  • Regułę projektu i ustawienie trybu uruchamiania, dzięki którym agent sam uruchamia testy, ale nie wykona niczego destrukcyjnego
  • Osiem promptów do skopiowania: zestawy testów z zachowania, ścieżki asynchroniczne i błędów, testy charakteryzacyjne, błąd jako nieprzechodzący test, luki w pokryciu, fabryki danych testowych, testy end-to-end z Playwright i diagnozę niestabilnych testów
  • Pięciopunktową listę dowodów, która mówi, czy testy napisane przez agenta potrafią złapać błąd, bez czytania każdego testu
  • Tabelę typowych awarii testów pisanych przez agenta i sposobów wyjścia z każdej

Wybierz wzorzec według tego, co wiesz o poprawnym zachowaniu. Źródło „poprawności” (wyrocznia) decyduje, co testy mogą sprawdzać.

Twoja sytuacjaWzorzecSkąd pochodzi „poprawne”
Nowa funkcja albo zmiana zachowaniaTest-driven development w CursorzeTwoja specyfikacja, napisana przed kodem
Działający kod, mało albo słabe testy, znane regułyZestaw testów z zachowaniaReguły biznesowe podane w prompcie
Kod legacy, którego nikt w pełni nie rozumieTesty charakteryzacyjneObecne zachowanie, zapisane przed zmianą
Błąd trafił na produkcjęBłąd jako nieprzechodzący testZgłoszenie błędu
Raport pokrycia pokazuje nietestowane gałęzieLuki w pokryciuReguły stojące za każdą niepokrytą gałęzią
Ścieżka użytkownika przechodzi przez strony i serwisyTesty end-to-end z Playwright MCPKryteria akceptacji ścieżki
Test pada raz na dziesięć uruchomieńDiagnoza niestabilnego testuIntencja testu, uczyniona deterministyczną

Przygotuj Cursora, żeby agent bezpiecznie uruchamiał testy

Dział zatytułowany „Przygotuj Cursora, żeby agent bezpiecznie uruchamiał testy”

Każdy wzorzec poniżej wymaga, by agent uruchomił zestaw testów, przeczytał błąd i spróbował ponownie. Skonfiguruj to raz na repozytorium.

  1. Pozwól uruchamiać polecenia testowe bez pytania. O tym, które polecenia terminala agent uruchamia bez pytania, Cursor decyduje w trybach uruchamiania (strona Run modes w sekcji Agent security dokumentacji Cursora, sprawdzona 28 sierpnia 2026). Nazw trybów i ścieżki ustawień nie dało się ponownie sprawdzić 26 września 2026, więc zweryfikuj je w swojej wersji. Wybierz tryb, który swobodnie uruchamia testy, sprawdzanie typów i linter, ale pyta przed wszystkim, co usuwa dane albo dotyka zdalnego repozytorium. Nie używaj trybu, który uruchamia każde polecenie bez nadzoru, poza jednorazowym sandboksem z ograniczoną siecią.

  2. Zapisz konwencje testowe w regule projektu. Reguła trzyma konwencje w każdej sesji, więc nie powtarzasz ich w każdym prompcie. Zakresy i położenie plików opisuje strona o regułach projektu.

  3. Zrób commit, zanim agent zacznie. Czysty commit sprawia, że git diff --stat pokazuje dokładnie, których plików dotknął agent, i tak wyłapiesz zmienioną asercję.

  4. Nazwij polecenie testowe wprost. Wpisz je do reguły (na przykład npx vitest run), żeby agent nie zgadywał między npm test, jest a nieaktualnym skryptem.

Reguła to instrukcja, a nie blokada. Żeby linia „nie edytuj testów” była egzekwowana, hooki Cursora mogą „obserwować, blokować albo modyfikować zachowanie” na etapach pętli agenta (cursor.com/docs/hooks, sprawdzone 28 sierpnia 2026). Strona Ochrona wyroczni pokazuje logikę blokady i kontrole CI, do których agent nie sięga.

Wygeneruj testy dla istniejącego kodu z zachowania, nie z implementacji

Dział zatytułowany „Wygeneruj testy dla istniejącego kodu z zachowania, nie z implementacji”

Najczęstsza porażka to zestaw, który opisuje kod zamiast wymagania. Gdy agent czyta payment-service.ts i pisze z niego testy, każdy test przechodzi przy pierwszym uruchomieniu, także na błędach. Podaj reguły sam i traktuj kod jak podejrzanego.

Test, który tu nie przechodzi, to najcenniejszy wynik sesji: albo podana reguła jest błędna, albo właśnie znalazłeś błąd w kodzie. Rozstrzygnij, które z nich, zanim ktokolwiek cokolwiek zmieni.

Ten sam kształt promptu działa na innych warstwach. Wskaż plik z konwencjami, żeby agent użył twoich zapytań i matcherów zamiast wymyślać nowe.

Write Vitest + React Testing Library tests for @src/components/UserProfile.tsx.
Cover: renders the name and avatar from props, falls back to initials when
the avatar is missing, calls onEdit once when the edit button is clicked, and
disables the edit button while `saving` is true. Query by role and label,
never by class name. Follow @src/components/__tests__/Card.test.tsx.

Testuj ścieżki asynchroniczne i błędów, które ukrywa pokrycie

Dział zatytułowany „Testuj ścieżki asynchroniczne i błędów, które ukrywa pokrycie”

Zielony test ścieżki szczęśliwej ukrywa ponowienie, timeout i odrzuconą obietnicę. Nazwij każdy przypadek i poproś o asercje liczby wywołań, bo „w końcu zwróciło dane” nie dowodzi, że logika ponowień zadziałała.

it('does not retry on a 4xx response', async () => {
const fetchMock = vi.fn().mockResolvedValue({ ok: false, status: 404 });
vi.stubGlobal('fetch', fetchMock);
await expect(fetchUserData(1)).rejects.toThrow(FetchUserError);
expect(fetchMock).toHaveBeenCalledOnce();
});

To linia toHaveBeenCalledOnce() łapie błąd. Bez niej klient, który trzy razy ponawia żądanie z odpowiedzią 404, nadal przechodzi.

W kodzie, którego nikt w pełni nie rozumie, nie podasz jeszcze reguł. Testy charakteryzacyjne zapisują, co kod robi dziś, łącznie z zachowaniem, które wygląda na błędne, więc refaktor zmieniający zachowanie zapali test na czerwono. To warunek wstępny refaktoryzacji legacy w Cursorze; metodę niezależną od narzędzia opisuje strona o testach charakteryzacyjnych.

Przejrzyj komentarze SUSPECT: z kimś, kto zna domenę. Każdy z nich staje się albo zgłoszeniem prawdziwego błędu, albo udokumentowaną regułą. Nie pozwól agentowi „naprawiać” ich w trakcie refaktoru, który nastąpi potem.

Zamień błąd z produkcji najpierw w nieprzechodzący test

Dział zatytułowany „Zamień błąd z produkcji najpierw w nieprzechodzący test”

Poprawka bez nieprzechodzącego testu to zgadywanie. Każ agentowi odtworzyć błąd jako test, pokazać ci porażkę i dopiero wtedy naprawiać. Pełną pętlę odtwórz–zdiagnozuj–napraw opisuje debugowanie z AI w Cursorze.

Wklejony wynik z kroku 1 jest dowodem. Test regresyjny, którego nikt nie widział na czerwono, niczego nie dowodzi o błędzie.

Procent pokrycia nie mierzy jakości: 100% pokrycia linii ze słabymi asercjami nadal przepuszcza błędy. Użyj raportu, żeby znaleźć gałęzie, których nikt nie testuje, a potem poproś o testy, które na ryzykownych gałęziach złapałyby regresję.

File | % Stmts | % Branch | % Funcs | % Lines
---------------|---------|----------|---------|--------
auth/login.ts | 75.00 | 66.67 | 100.00 | 75.00
auth/reset.ts | 45.00 | 33.33 | 66.67 | 45.00

W takim raporcie auth/reset.ts ma najcieńsze pokrycie gałęzi, więc przypadki brzegowe resetu hasła (wygasły token, już użyty token, nieznany e-mail) warto napisać jako pierwsze. Żeby --coverage działało, Vitest potrzebuje zainstalowanego dostawcy pokrycia, na przykład @vitest/coverage-v8. Ustaw coverage.include: ["src/**"] w konfiguracji Vitest, bo inaczej pliki bez żadnych testów w ogóle nie trafią do raportu. Jak zmierzyć, czy testy łapią błędy, a nie tylko dotykają linii, opisuje strona o sile wyroczni.

Obiekty wpisane w każdym teście rozjeżdżają się z prawdziwymi typami i wydłużają test ponad sprawdzane zachowanie. Poproś o fabryki raz i wpisz nazwę pliku do reguły testowej.

Dobry wynik wygląda tak:

let seq = 0;
const nextId = () => ++seq;
export function createUser(overrides: Partial<User> = {}): User {
const id = nextId();
return { id: `user-${id}`, email: `test-${id}@example.com`, name: 'Test User', ...overrides };
}

Weryfikacją jest tu sprawdzanie typów: jeśli User dostanie nowe wymagane pole, fabryka przestanie się kompilować, zamiast po cichu tworzyć niepoprawne dane. Współdzielone fixture’y, seedowanie i zanonimizowane dane produkcyjne opisuje strona o zarządzaniu danymi testowymi.

Przy ścieżkach przechodzących przez kilka stron serwer Playwright MCP (@playwright/mcp) pozwala agentowi sterować prawdziwą przeglądarką, więc może napisać test Playwright i od razu uruchomić go na lokalnej aplikacji. Dodaj go do pliku .cursor/mcp.json w projekcie; inne miejsca konfiguracji opisuje konfiguracja MCP.

{
"mcpServers": {
"playwright": {
"command": "npx",
"args": ["@playwright/mcp@latest", "--isolated"]
}
}
}

--isolated trzyma profil przeglądarki w pamięci. README Playwrighta zaznacza, że trwałego profilu może naraz używać tylko jedna instancja przeglądarki, więc bez tej flagi równoległe agenty wchodzą sobie w drogę. Stary pakiet @modelcontextprotocol/server-puppeteer jest zarchiwizowany; używaj serwera Playwright. Jego schematy narzędzi i zrzuty stron zajmują kontekst, więc włączaj go do pracy nad UI, a nie w każdej sesji.

test('shows an error for invalid credentials', async ({ page }) => {
await page.goto('/login');
await page.getByLabel('Email').fill('user@example.com');
await page.getByLabel('Password').fill('wrong-password');
await page.getByRole('button', { name: 'Sign in' }).click();
await expect(page.getByRole('alert')).toContainText('Invalid credentials');
});

Dostępne lokatory przetrwają refaktory CSS, które psują selektory #id i .class, a do tego zawodzą, gdy kontrolka traci etykietę, czyli łapią błąd dostępności. W CI działa zacommitowany plik ze specyfikacją, a nie sesja przeglądarki agenta. Szerszą strategię E2E opisuje strona o automatyzacji testów end-to-end.

Zdiagnozuj niestabilny test powtarzanymi uruchomieniami

Dział zatytułowany „Zdiagnozuj niestabilny test powtarzanymi uruchomieniami”

Test, który pada raz na dziesięć uruchomień, zabiera więcej czasu niż taki, który pada zawsze. Przewaga agenta polega na tym, że uruchomi test wiele razy z rzędu i się nie znudzi.

Dla testów jednostkowych w Vitest zrób pętlę w terminalu: for i in $(seq 25); do npx vitest run src/cart/__tests__/cart.test.ts || echo FAIL; done. Poprawką jest zwykle izolacja, czyli hook sprzątający albo poczekanie na ustabilizowanie stanu, a nie dłuższy timeout. Wyścigi wymagające głębszego dochodzenia należą do strony o polowaniu na błędy.

Jak zweryfikować testy agenta bez czytania wszystkich?

Dział zatytułowany „Jak zweryfikować testy agenta bez czytania wszystkich?”

Sprawdź, czy testy potrafią nie przejść i czy nikt ich nie nagiął do kodu. Wymagaj tych dowodów w każdym pull requeście, który dodaje testy, a kod testów czytaj tylko tam, gdzie czegoś brakuje albo coś zaskakuje.

  1. Czerwony przed zielonym. Nowe testy nowego zachowania albo poprawki nie przechodzą na starym kodzie, a wynik porażki jest w pull requeście. Wyjątkiem są testy charakteryzacyjne: z założenia przechodzą.
  2. Próba zepsucia. Dla każdego nowego testu agent robi najmniejszą zmianę, która powinna go zepsuć, pokazuje porażkę i cofa zmianę. Test, który zostaje zielony, jest ozdobą. Strona o sile wyroczni skaluje to do testów mutacyjnych całego zestawu.
  3. Testy nietknięte podczas poprawki. git diff --stat commita z implementacją nie wymienia żadnego pliku testowego.
  4. Żadnych pustych mocków. Prompt poniżej znajduje testy, które przeszłyby po usunięciu implementacji.
  5. Bramki zielone w CI, nie tylko w raporcie agenta: testy, tsc --noEmit i linter. Podłącza je strona o CI/CD z Cursorem.

Za te dowody odpowiada programista, który otworzył pull request. Recenzent, człowiek albo Bugbot, zatwierdza, gdy wszystkie punkty są spełnione. Uzasadnienie przeglądu dowodów zamiast diffów znajdziesz na stronie dowody, nie diffy.

ObjawPrawdopodobna przyczynaWyjście
Każdy nowy test przechodzi za pierwszym razemTesty powstały z implementacjiUruchom ponownie prompt „z zachowania” z podanymi regułami i src/ tylko do odczytu
Nieprzechodzący test zazielenił się po zmianie pliku testowego (toBe zmienione na toBeDefined)Agent osłabił asercjęCofnij plik testowy, napisz „The test is correct; fix the implementation” i sprawdź git diff --stat
Testy przechodzą, a funkcja nie działaNadmiar mocków: testy sprawdzają mockaUruchom prompt o pustych mockach; zostaw co najmniej jeden test integracyjny albo E2E przechodzący przez prawdziwą granicę między komponentami
Pokrycie rośnie, a błędy dalej uciekająTesty wykonują linie, ale nie sprawdzają wynikówZrób próbę zepsucia na module, z którego uciekł błąd
Testy przechodzą lokalnie, padają w CIPrawdziwe zegary, losowe wartości, współdzielony stan albo inne środowiskoDodaj do reguły zakaz zegarów i losowości; odtwórz błąd poleceniem z CI i tymi samymi danymi
Agent uruchomił polecenie, które usunęło dane albo zrobiło pushTryb uruchamiania, który przepuszcza każde poleceniePrzełącz się na tryb pytający przed poleceniami destrukcyjnymi i zdalnymi; przywróć stan z commita sprzed sesji
Testy Playwright od razu padają z błędami połączeniaSerwer deweloperski nie działa albo działa na innym porcieUruchom aplikację, wpisz dokładny URL do promptu i każ agentowi poczekać na odpowiedź serwera przed nawigacją
Niestabilny test „naprawiony” dłuższym timeoutemWyścig został ukryty, a nie usuniętyPoproś o przyczynę z dowodem w logach i 25 zaliczonych uruchomień z rzędu
Agent pisze kod na pięć funkcji zamiast zazielenić jeden testPętla jest za szerokaPrzerwij: „Stop. Make only the failing refund test pass, then run the suite.” Ciasna pętla daje lepszy kod niż jedna duża generacja
Jeden plik testowy przerasta kilkaset liniiJeden plik na serwis zbiera wszystkie domenyPoproś agenta o podział według zachowania (auth, zwroty, webhooki) i uruchom testy przed podziałem i po nim

Mapę sekcji znajdziesz w przeglądzie testowania i debugowania w Cursorze. Ten sam etap w innych narzędziach: testowanie z Claude Code i testowanie z Codeksem.