Generowanie testów i TDD z Claude Code
ENGenerowanie testów w Claude Code działa wtedy, gdy test jest kontraktem: Claude Code kopiuje wzorce istniejących testów, najpierw pisze test, który nie przechodzi, implementuje kod przy zablokowanym pliku testów i po każdej edycji ponownie uruchamia zestaw przez hooki. Testy mutacyjne i CI dowodzą potem, że zestaw łapie błędy, bez czytania każdej wygenerowanej linii.
Twój endpoint zamówień przechodzi wszystkie testy jednostkowe, odznaka pokrycia pokazuje 94%, a na produkcji i tak lecą błędy 500, bo nic nigdy nie sprawdziło ścieżki, w której płatność się udaje, a zapis do bazy nie. Testy były zielone, bo sprawdzały, czy wywołano mocki. Teraz tech lead prosi o testy do kolejnej funkcji, a ty chcesz zestawu, który czerwienieje z właściwych powodów, a nie ściany zielonych znaczków.
Ta strona jest dla programistów, którzy pracują z Claude Code w terminalu, i dla tech leadów, którzy chcą tej samej dyscypliny testów na każdej gałęzi. Zakłada zainstalowany i skonfigurowany Claude Code; jeśli go nie masz, zacznij od przeglądu testowania i debugowania w Claude Code i konfiguracji projektu.
Co zyskasz, generując testy z Claude Code
Dział zatytułowany „Co zyskasz, generując testy z Claude Code”- Parę hooków, która po każdej edycji uruchamia powiązane testy i nie pozwala Claude zakończyć pracy przy czerwonym zestawie.
- Pętlę red-green-refactor, w której sesja implementująca nie może edytować pliku testów.
- Prompty do wklejenia: testy zgodne z wzorcami, testy integracyjne na styku z usługami zewnętrznymi i odporne na niestabilność testy Playwright.
- Test mutacyjny, który pokazuje, czy wygenerowany zestaw łapie błędy, bez czytania go linijka po linijce.
- Skill
/test-routei bezobsługowe zadanie CI do diagnozy testów, które możesz dodać do repozytorium jeszcze dziś.
Kto co sprawdza, gdy testy pisze Claude Code?
Dział zatytułowany „Kto co sprawdza, gdy testy pisze Claude Code?”Zmiana polega na tym, że zatwierdzasz zachowanie, a nie linie kodu. Podziel pracę tak, żeby każdy wygenerowany artefakt miał kontrolę, która nie jest opinią samego modelu.
| Artefakt | Kto go tworzy | Jak jest weryfikowany | Kto zatwierdza |
|---|---|---|---|
| Lista zachowań do przetestowania | Ty albo Claude na podstawie specyfikacji | Czytasz listę nazw testów (10–20 linii, nie kod) | Ty |
| Test, który nie przechodzi | Claude | Jest czerwony z podanego powodu, zanim powstanie implementacja | Pokazuje to wynik hooka |
| Implementacja | Claude, przy zablokowanych testach | Zestaw zielenieje; plik testów w diffie się nie zmienia | CI |
| Siła zestawu | Claude, na żądanie | Test mutacyjny: wstrzyknięte błędy muszą zaczerwienić zestaw | Recenzent czyta listę błędów, które przeżyły |
| Merge | CI | Sprawdzanie typów, lint, pełny zestaw, pokrycie zmienionych plików | Właściciel kodu (z CODEOWNERS) ocenia dowody, a nie każdą linię |
Skąd biorą się kryteria akceptacji przed startem tej pętli, opisuje strona wykonywalne kryteria akceptacji. Co pull request musi dołączyć jako dowód, opisuje pakiet dowodów.
Skonfiguruj pętlę informacji zwrotnej z testów, zanim cokolwiek wygenerujesz
Dział zatytułowany „Skonfiguruj pętlę informacji zwrotnej z testów, zanim cokolwiek wygenerujesz”Claude Code pisze lepsze testy, gdy polecenie testowe jest w jego instrukcjach, a wyniki wracają do niego automatycznie. Zrób to raz na repozytorium.
-
Wpisz dokładne polecenia testowe do
CLAUDE.md. Claude użyje tego, co tam znajdzie, zamiast zgadywać międzynpm test,npx vitesta celem w Makefile.## Tests- Run one file: `npx vitest run src/routes/orders.test.ts`- Run tests related to a changed file: `npx vitest related src/routes/orders.ts --run`- Full suite: `npx vitest run`- Tests live next to the code as `*.test.ts`. Never edit a test to make it pass. -
Dodaj hook
PostToolUse, który po każdej edycji uruchamia powiązane testy. Standardowe wyjście hookaPostToolUsenie trafia do Claude; dopiero kod wyjścia 2 przekazuje jego standardowe wyjście błędów do rozmowy. Zapisz to jako.claude/hooks/test-related.shi nadaj prawo wykonania (chmod +x):#!/usr/bin/env bash# PostToolUse: run the tests that cover the file Claude just editedfile=$(jq -r '.tool_input.file_path // empty')case "$file" in*.ts|*.tsx) ;;*) exit 0 ;;esacif ! out=$(npx vitest related "$file" --run 2>&1); thenecho "$out" | tail -40 >&2exit 2fi -
Dodaj hook
Stop, który uruchamia pełny zestaw, zanim Claude zgłosi koniec. Kod wyjścia 2 w hookuStoppodtrzymuje rozmowę, a błąd trafia do Claude jako informacja zwrotna. Zapisz to jako.claude/hooks/suite-before-stop.sh:#!/usr/bin/env bash# Stop: do not let Claude finish while the suite is redif ! out=$(npx vitest run 2>&1); thenecho "The test suite is failing. Fix the code, not the tests:" >&2echo "$out" | tail -60 >&2exit 2fi -
Zarejestruj oba hooki w
.claude/settings.jsoni dodaj plik razem ze skryptami do repozytorium (commit), żeby cały zespół dostał tę samą pętlę:{"hooks": {"PostToolUse": [{"matcher": "Edit|Write","hooks": [{ "type": "command", "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/test-related.sh" }]}],"Stop": [{"hooks": [{ "type": "command", "command": "${CLAUDE_PROJECT_DIR}/.claude/hooks/suite-before-stop.sh" }]}]}}
Generuj testy zgodne z istniejącymi wzorcami
Dział zatytułowany „Generuj testy zgodne z istniejącymi wzorcami”Najczęstsza skarga na generowane testy to rozjazd stylu: inne podejście do mocków, inne nazewnictwo, nowy helper do fikstur, który dubluje istniejący. Rozwiązanie: każ Claude przeczytać dwa dobre pliki testowe, zanim cokolwiek napisze, i wymień ścieżki błędów, które musi pokryć.
Ostatni akapit oszczędza najwięcej czasu przy przeglądzie. Zatwierdzasz listę 10–20 zachowań, co zajmuje minutę, zamiast czytać 300 linii kodu testów. Jeśli na liście brakuje zachowania, na którym ci zależy, dopisz je, zanim powstanie choć jedna linia.
Przy fiksturach wskaż Claude schemat i istniejącą fabrykę („follow the pattern of createTestUser() in tests/fixtures/user.fixtures.ts”) i poproś o warianty brzegowe, na przykład organizację z maksymalną liczbą członków albo z wygasłym okresem próbnym. Seedowanie i izolację danych opisuje szczegółowo strona zarządzanie danymi testowymi.
Prowadź red-green-refactor z zablokowanym plikiem testów
Dział zatytułowany „Prowadź red-green-refactor z zablokowanym plikiem testów”Test, który nigdy nie był czerwony, nie jest testem. Poniższa pętla sprawia, że czerwony krok jest widoczny, a sesji implementującej znacznie trudniej „naprawić” błąd, edytując asercję. To najczęstszy sposób, w jaki zestawy pisane przez agenta kłamią. Reguły deny dla Edit obejmują narzędzia plikowe i przekierowania powłoki, ale nie skrypt, który sam zapisuje pliki; resztę wyłapuje sprawdzenie git diff w kroku 4.
Przykładem przewodnim jest endpoint Express, który pobiera płatność, a potem zapisuje zamówienie przez Drizzle ORM. Ma dwie rzeczy, które psują się na produkcji: wywołanie zewnętrzne i zapis do bazy, który może się nie udać już po nim.
import { Router } from 'express';import { db } from '../db';import { orders } from '../db/schema';import { charge, PaymentError } from '../lib/payments';
export const ordersRouter = Router();
ordersRouter.post('/orders', async (req, res) => { const { userId, amountCents, idempotencyKey } = req.body; if (!userId || !amountCents) { return res.status(400).json({ error: 'userId and amountCents required' }); } try { const payment = await charge({ amountCents, idempotencyKey }); const [order] = await db .insert(orders) .values({ userId, amountCents, paymentId: payment.id, status: 'paid' }) .returning(); return res.status(201).json(order); } catch (err) { if (err instanceof PaymentError) return res.status(402).json({ error: 'payment_failed' }); // The charge succeeded but the write failed: the dangerous case return res.status(503).json({ error: 'order_persist_failed', retryable: true }); }});-
Napisz czerwony test w sesji, która może edytować tylko pliki testów. Uruchom czerwony krok bezobsługowo z
--permission-mode dontAsk, który odrzuca każde wywołanie narzędzia, które wymagałoby pytania. Reguły ścieżekEdit(...)obejmują wszystkie narzędzia zapisujące pliki, takżeWrite, więc ta sesja może tworzyć i zmieniać pliki*.test.tswsrc/i nic poza nimi.Okno terminala claude -p "Write ONE Vitest + supertest test in src/routes/orders.test.ts:a second POST /orders with the same idempotencyKey must not call charge()again. Mock only the payment provider and the Drizzle insert. Do not touchthe route. Run the test and show me the failure output." \--permission-mode dontAsk \--allowedTools "Read" "Grep" "Glob" "Edit(src/**/*.test.ts)" "Bash(npx vitest *)" -
Sprawdź, że test nie przechodzi z właściwego powodu. Błąd musi być niespełnioną asercją (
chargewywołane dwa razy), a nie brakującym importem czy literówką. Powyższy endpoint przekazuje klucz do dostawcy płatności, ale nigdy nie sprawdza, czy zamówienie już istnieje, więc ten test jest czerwony z powodu prawdziwej luki. -
Implementuj w sesji, która nie może edytować testów. Uruchom sesję interaktywną z regułą deny na pliki testów; reguła deny wygrywa z każdą regułą allow.
Okno terminala claude --disallowedTools "Edit(**/*.test.ts)"Potem wpisz: „Make src/routes/orders.test.ts pass with the smallest change to src/routes/orders.ts. You cannot edit test files. If you think the test is wrong, stop and tell me why.”
-
Sprawdź, że plik testów się nie zmienił.
git diff --statpowinien pokazać tylko endpoint. Jeśli używasz hooków z poprzedniej sekcji, hookStopjuż uruchomił pełny zestaw. -
Refaktoryzuj przy zielonym pasku. Poproś o konkretny refaktoring („extract the idempotency lookup into
findOrderByKey”); hookPostToolUseuruchamia powiązane testy po każdej edycji.
Ostatnia instrukcja jest ważna: test zielony przy pierwszym uruchomieniu albo opisuje zachowanie, które już istnieje, albo niczego nie sprawdza. W obu przypadkach chcesz o tym wiedzieć. Wersję tej pętli dla wszystkich narzędzi, z uzasadnieniem każdego kroku, znajdziesz na stronie TDD ze wsparciem AI. Blokowanie testów w skali zespołu, z CODEOWNERS i kontrolami należącymi do CI, opisuje ochrona wyroczni.
Pisz testy integracyjne na styku z usługami, a nie przeciwko mockom
Dział zatytułowany „Pisz testy integracyjne na styku z usługami, a nie przeciwko mockom”Zestawy przeładowane mockami przechodzą, bo nigdy nie dotykają granicy, na której psuje się produkcja. Mockuj tylko prawdziwe krawędzie zewnętrzne (wywołanie HTTP dostawcy płatności, zachowanie sterownika bazy przy awarii), a wszystko pomiędzy uruchamiaj naprawdę.
Dobry wynik sprawdza zachowanie (status, treść odpowiedzi, liczbę wywołań), a nigdy szczegóły implementacji:
import request from 'supertest';import { beforeEach, expect, it, vi } from 'vitest';import { app } from '../app';import { db } from '../db';import { charge } from '../lib/payments';
vi.mock('../lib/payments', async (importOriginal) => ({ ...(await importOriginal<typeof import('../lib/payments')>()), charge: vi.fn(),}));
beforeEach(() => { vi.mocked(charge).mockReset(); vi.restoreAllMocks();});
it('returns a retryable 503 when the insert fails after a charge', async () => { vi.mocked(charge).mockResolvedValue({ id: 'pay_123' }); vi.spyOn(db, 'insert').mockImplementation(() => { throw new Error('connection terminated'); });
const res = await request(app) .post('/orders') .send({ userId: 'u1', amountCents: 4999, idempotencyKey: 'k1' });
expect(res.status).toBe(503); expect(res.body).toMatchObject({ retryable: true }); expect(charge).toHaveBeenCalledTimes(1);});Jeśli testy integracyjne uruchamiasz na prawdziwej bazie zamiast mockowanego inserta, podłącz serwer MCP bazy danych, żeby Claude czytał prawdziwy schemat i ograniczenia zamiast je zgadywać; utrzymywane opcje wymienia strona serwery MCP baz danych. Kontenery, transakcje i testy kontraktowe we wszystkich trzech narzędziach opisuje strona wzorce testów integracyjnych.
Jak pisać testy end-to-end, które przetrwają CI
Dział zatytułowany „Jak pisać testy end-to-end, które przetrwają CI”Testy end-to-end są niestabilne, gdy test ściga się z aplikacją: kliknięcie, zanim przycisk stanie się aktywny, asercja przed zakończeniem wywołania sieciowego, stałe oczekiwanie, które działa na laptopie i zawodzi na wolniejszym runnerze. Daj Claude przeglądarkę, żeby czytał prawdziwy DOM zamiast wymyślać selektory. Dodaje ją serwer Playwright MCP (@playwright/mcp, wersja 0.0.82 w npm 2026-09-26):
claude mcp add playwright -- npx @playwright/mcp@latest--repeat-each=3 zamienia jednorazowe wygenerowanie testu w sprawdzian stabilności, zanim test trafi do pipeline’u. Do sprawdzenia zmiany w działającej aplikacji bez żadnego pliku testów służy wbudowany skill /verify, który buduje aplikację i nią steruje; pozostałe opcje porównują strony agent-browser i serwery MCP przeglądarki.
Skąd wiesz, że wygenerowane testy łapią błędy?
Dział zatytułowany „Skąd wiesz, że wygenerowane testy łapią błędy?”Pokrycie linii mierzy, które linie się wykonały, a nie to, czy cokolwiek je sprawdziło. Siłę zestawu udowodnisz bez czytania go, sprawdzając, czy łapie błędy podłożone celowo.
Zanim uruchomisz ten prompt, zatwierdź w repozytorium albo odłóż przez git stash własne zmiany w endpoincie, żeby przypadkowe cofnięcie nie zabrało prawdziwej pracy.
Błąd, który przeżył, to brakująca asercja, a tabela ocalałych błędów jest artefaktem, który czyta recenzent. Jeśli chcesz powtarzalnego wyniku zamiast promptu, uruchom w CI narzędzie mutacyjne: Stryker (@stryker-mutator/core z @stryker-mutator/vitest-runner, oba w wersji 10.0.0 w npm 2026-09-26) automatycznie mutuje kod i raportuje wynik mutacyjny. Progi, które zestaw powinien przekroczyć, zanim pozwolisz pętli działać bez nadzoru, wyznacza strona jak silna jest twoja wyrocznia?.
Trzy tańsze kontrole wyłapują większość słabych zestawów jeszcze przed testem mutacyjnym:
- Dowód czerwonego kroku. Każdy nowy test był widziany jako czerwony, a wynik jest w sesji albo w pull requeście.
- Stabilność. Nowe testy przechodzą trzy razy z rzędu: uruchom plik trzy razy albo użyj
--repeat-each=3w Playwright. - Drugi czytelnik, który nie pisał testów. Poproś świeży subagent: „Review the tests added on this branch. For each one, state the behaviour it verifies in one sentence. Flag any test that would still pass if the function under test returned a constant, and any assertion on internal calls rather than outputs.” Świeży kontekst nie jest przywiązany do testów, które ocenia.
Zamknij przepis w skillu /test-route
Dział zatytułowany „Zamknij przepis w skillu /test-route”Własne polecenia są teraz w Claude Code skillami: plik .claude/skills/<nazwa>/SKILL.md tworzy /<nazwa>, a istniejące pliki w .claude/commands/ nadal działają. Wpisz stos technologiczny i obowiązkowe przypadki do samego skilla, żeby każde wywołanie dawało ten sam plan testów zamiast „comprehensive tests”.
---name: test-routedescription: Write Vitest + supertest integration tests for one Express route, including failure and idempotency cases.argument-hint: "[METHOD /path]"disable-model-invocation: trueallowed-tools: Read Grep Glob Bash(npx vitest *)---Write integration tests for the Express route: $ARGUMENTS
Stack: Express, Drizzle ORM (Postgres), Vitest, supertest.Run the real middleware and handler. Mock only external services and the DB.
First list the test names and wait for approval. Always include, one it() each:- happy path (correct status and persisted row)- input validation (400 on missing required fields)- external dependency throws (the mapped error status, for example 402)- DB write fails AFTER an external side effect (a retryable 5xx)- idempotency: a repeated request with the same key has no second effect
Assert status codes and specific body fields. No snapshot tests.Reset mocks in beforeEach. Run the new file and show it red or green per case.Never edit the route in this skill.Wywołujesz go poleceniem /test-route POST /orders. disable-model-invocation: true sprawia, że Claude nie uruchomi go sam z siebie, a allowed-tools z góry zatwierdza na tę turę tylko odczyt i runner testów. Argumenty i pliki pomocnicze opisuje strona własne polecenia i skille.
Jeśli wolisz zainstalować utrzymywany skill TDD, zamiast pisać własny, dwa są szeroko używane. Skill tdd Matta Pococka i skill test-driven-development z Superpowers wymuszają red-green-refactor. W skills.sh miały odpowiednio około 967 000 i 237 000 instalacji łącznie według zrzutu z 2026-09-26 opublikowanego przez LinklyAI/best-skills (źródło wtórne):
npx skills add mattpocock/skills --skill tdd -a claude-codenpx skills add obra/superpowers --skill test-driven-development -a claude-codeKażdy zainstalowany skill dodaje swój opis do kontekstu każdej sesji, więc zainstaluj ten, którego będziesz używać, a nie oba. (claude plugin install mattpocock-skills instaluje cały zestaw inżynierski Pococka zamiast pojedynczego skilla).
Diagnozuj testy bezobsługowo w CI
Dział zatytułowany „Diagnozuj testy bezobsługowo w CI”Ta sama dyscyplina działa bez ciebie. W CI wywołuj Claude tylko wtedy, gdy zestaw jest czerwony, i daj mu wyłącznie odczyt: zdiagnozuje błąd, ale nie przepisze testów, żeby się zazieleniły. Testy uruchamiają się w osobnym zadaniu, bez żadnego sekretu w środowisku, a zadanie agenta czyta ich wynik z artefaktu na świeżym runnerze: krok testów może zapisać do GITHUB_ENV albo GITHUB_PATH i w ten sposób sięgnąć do każdego kolejnego kroku tego samego zadania. Nigdy nie pozwalaj agentowi uruchamiać kodu z pull requesta, gdy ustawione jest ANTHROPIC_API_KEY: plik testu, konfiguracja Vitesta albo hook projektu z PR mógłby odczytać klucz. --bare pomija automatyczne wykrywanie hooków, pluginów i CLAUDE.md, a serwery MCP trzeba mu podać jawnie przez --mcp-config. --restricted ignoruje pliki ustawień z PR (więc jego .claude/settings.json nie nada sobie uprawnień) i usuwa Bash oraz pozostałe narzędzia uruchamiające kod (sprawdzone w v2.1.283). --setting-sources "" nie wczytuje żadnego pliku ustawień, a --strict-mcp-config to dodatkowe zabezpieczenie przed .mcp.json z PR. --max-budget-usd ogranicza koszt jednego uruchomienia. Bramką merge pozostaje twoje zwykłe zadanie testowe; to zadanie tylko wyjaśnia błąd. Przy wyzwalaczu pull_request GitHub uruchamia ten plik workflow z merge refu PR, więc pull request z gałęzi w twoim repozytorium mógłby go zmienić i ujawnić klucz (pull requesty z forków nie dostają sekretów). Zanim dodasz sekret, wpisz /.github/ do CODEOWNERS i wymagaj review właściciela kodu.
name: test-triageon: [pull_request]permissions: contents: readjobs: tests: runs-on: ubuntu-latest outputs: outcome: ${{ steps.tests.outcome }} steps: - uses: actions/checkout@v7 with: persist-credentials: false - uses: actions/setup-node@v7 with: node-version: 22 - run: npm ci # The PR's own code (tests, vitest config) runs here, in a job with NO secret. - id: tests run: npx vitest run --reporter=verbose > test-output.txt 2>&1 continue-on-error: true - uses: actions/upload-artifact@v7 with: name: test-output path: test-output.txt triage: needs: tests if: needs.tests.outputs.outcome == 'failure' runs-on: ubuntu-latest steps: # A fresh runner: nothing the PR's code wrote in the tests job reaches this one. # Install before checkout, so a .npmrc in the PR cannot steer the install. - uses: actions/setup-node@v7 with: node-version: 22 - run: npm install -g @anthropic-ai/claude-code - uses: actions/checkout@v7 with: persist-credentials: false - uses: actions/download-artifact@v8 with: name: test-output # The agent only reads: no Bash, no project hooks, settings or MCP servers from the PR. - name: Triage failing tests run: | claude -p "Read test-output.txt. Name each failing test, the likely root cause and a one-line fix. Do not edit files." \ --bare --restricted --setting-sources "" --strict-mcp-config \ --permission-mode dontAsk \ --allowedTools "Read" "Grep" "Glob" \ --max-budget-usd 2 \ --output-format json > triage.json env: ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}Żeby opublikować wynik jako komentarz w pull requeście albo pozwolić Claude otworzyć kolejny pull request z brakującymi testami, użyj GitHub Action anthropics/claude-code-action@v1; pełny workflow opisuje strona integracja z CI/CD. Nie wkładaj generowania testów do samej bramki merge: wygenerowane testy przychodzą jako pull request, który przechodzi przez te same hooki, test mutacyjny i przegląd co każda inna zmiana.
Do jednorazowego uzupełnienia brakujących plików testów na gałęzi uruchom w pętli uprawnienia z czerwonego kroku. < /dev/null jest tu niezbędne: claude -p czyta stdin z potoku, więc bez tego pierwsze wywołanie połyka resztę listy plików i pętla uzupełnia tylko jeden plik.
git diff --name-only main...HEAD -- 'src/*.ts' ':!*.test.ts' |while read -r file; do test_file="${file%.ts}.test.ts" [ -f "$test_file" ] && continue claude -p "Read $file and two neighbouring *.test.ts files. Write $test_file in the same style, covering every exported function and every thrown error. Run it with npx vitest run $test_file and report the result." \ --permission-mode dontAsk \ --allowedTools "Read" "Grep" "Glob" "Edit(src/**/*.test.ts)" "Bash(npx vitest *)" \ < /dev/nulldoneTesty pisane po kodzie opisują to, co kod robi, łącznie z błędami. Zanim zaufasz wynikowi, uruchom na nim test mutacyjny.
Co się psuje, gdy testy pisze Claude Code?
Dział zatytułowany „Co się psuje, gdy testy pisze Claude Code?”Claude „naprawił” czerwony test, osłabiając asercję. Poproszony o zazielenienie testów agent potrafi edytować test zamiast kodu. Jak wyjść: przywróć plik testów przez git checkout -- <plik>, uruchom sesję implementacji ponownie z --disallowedTools "Edit(**/*.test.ts)" i dodaj w CI kontrolę, która odrzuca pull request zmieniający jednocześnie test i kod, który ten test pokrywa, bez etykiety tests-changed. Pełny wzorzec opisuje ochrona wyroczni.
Zestaw jest zielony, a produkcja i tak się psuje. Testujesz mocki, a nie styki z usługami. Jak wyjść: uruchom ponownie prompt integracyjny i wymuś prawdziwe wykonanie wszystkiego poza właściwą granicą zewnętrzną. Jeśli mock i prawdziwe API mogą się rozjechać, dodaj test kontraktowy uruchamiany co noc na sandboksie dostawcy.
Hook działa, ale Claude nigdy nie reaguje na błędy. Hook PostToolUse, który kończy się kodem 0 lub 1, jest dla Claude niewidoczny. Jak wyjść: niech skrypt wypisze błąd na standardowe wyjście błędów i wykona exit 2, jak w skrypcie powyżej, a potem sprawdź w transkrypcie informację zwrotną z hooka.
Hook Stop spowalnia każdą turę. Pełny zestaw przy każdym zatrzymaniu kosztuje minuty. Jak wyjść: skieruj hook Stop na szybki projekt jednostkowy, hook PostToolUse zostaw tylko na powiązanych testach, a testy integracyjne i end-to-end oddaj CI.
Testy end-to-end przechodzą lokalnie i są niestabilne w CI. Prawie zawsze to wyścig. Jak wyjść: wyszukaj w pliku waitForTimeout i usuń każde wystąpienie, zastąp je asercją web-first albo toHaveURL i uruchom ponownie z --repeat-each=3.
Testy psują się przy każdym bezpiecznym refaktoringu. Sprawdzają implementację. Jak wyjść: „These tests break on safe refactors. Rewrite them to assert observable behaviour (inputs, outputs, status codes, persisted state), never private method names or call order unless the order is the contract.”
Testy przechodzą pojedynczo, a razem nie. Współdzielony, modyfikowalny stan. Jak wyjść: „Each test must be independent. Find shared variables that tests modify, reset state in beforeEach, and wrap database tests in a transaction that rolls back.”
Uruchomienie bezobsługowe nic nie zrobiło. W trybie -p z dontAsk każde wywołanie narzędzia, które wymagałoby pytania, a nie jest na liście dozwolonych, jest odrzucane bez pytania. Jak wyjść: uruchom ponownie z --output-format json, odczytaj z wyniku odrzucone wywołania i poszerz listę dozwolonych o najwęższą regułę, która je obejmuje.
Dokąd dalej z testowaniem w Claude Code
Dział zatytułowany „Dokąd dalej z testowaniem w Claude Code”Pracujesz na tym samym repozytorium innym narzędziem? Odpowiedniki tej strony to testowanie z Codex i TDD w Cursorze.