Przejdź do głównej zawartości

Generowanie i wykonywanie testów z CLI

Twój PR jest gotowy. Funkcjonalność działa, kod jest czysty, a twój tech lead zadaje pytanie, którego chciałeś uniknąć: “Gdzie są testy?” Wiesz, że powinieneś był je napisać najpierw. Ale TDD wydawało się wolne, gdy byłeś w flow, a teraz pisanie testów po fakcie jest jak odrabianie zaległości. Moduł ma cztery zależności wymagające mockowania, ścieżki błędów są trudne do ręcznego wywołania, a istniejące pliki testowe używają wzorców, których nie do końca przyswoiłeś.

Claude Code eliminuje to tarcie. Wskazujesz go na kod, mówisz mu, żeby pasował do istniejących wzorców testów, i generuje zestaw testów pokrywający ścieżkę sukcesu, ścieżki błędów i przypadki brzegowe, o których zapomniałeś. Następnie uruchamia testy po każdej zmianie, więc zawsze wiesz, co jest zepsute.

  • Workflow do generowania testów pasujących do istniejących wzorców projektu
  • Pętla red-green-refactor wspierana przez Claude uruchamiającego testy po każdej edycji
  • Prompty do wykrywania luk w pokryciu i celowanego generowania testów
  • Wzorce trybu headless do automatycznego generowania testów w CI

Największym problemem z testami generowanymi przez AI jest niedopasowanie stylu. Domyślny styl testów Claude może nie pasować do twojego. Rozwiązanie jest proste: pokaż mu swoje istniejące testy, zanim poprosisz o napisanie nowych.

Claude czyta twoje istniejące testy, identyfikuje wzorce (Jest vs Vitest, funkcje fabrykujące vs inline mocks, płaskie describe blocks vs zagnieżdżone describes) i generuje nowe testy, które wyglądają, jakby należały do projektu.

TDD z Claude Code jest szybsze niż tradycyjne TDD, ponieważ Claude zajmuje się szablonem, podczas gdy ty koncentrujesz się na tym, co kod powinien robić.

  1. Opisz zachowanie, które chcesz zaimplementować

    I need a function calculateShippingCost that takes an order
    object and returns the shipping cost. Rules:
    - Orders over $100 ship free
    - Standard shipping is $5.99
    - Express shipping is $14.99
    - International orders add a $10 surcharge
    - Weight over 50lbs adds $0.50 per additional pound
  2. Poproś Claude o napisanie testów najpierw

    Write tests for calculateShippingCost based on those rules.
    Follow the patterns in tests/utils/pricing.test.ts.
    Include edge cases: exactly $100 order, exactly 50lbs,
    zero-weight digital goods, negative amounts (should throw).
    Do NOT write the implementation yet.
  3. Uruchom testy, aby potwierdzić, że nie przechodzą

    Run the tests. They should all fail since the function
    doesn't exist yet. Show me the output.
  4. Zaimplementuj, aby testy przeszły

    Now implement calculateShippingCost in src/utils/pricing.ts.
    Make all the tests pass. Use the simplest implementation
    that satisfies the tests.
  5. Uruchom testy ponownie, aby potwierdzić sukces

    Run the tests. Show me which pass and which fail.
    Fix any failures.
  6. Refaktoryzuj z siatką bezpieczeństwa

    The implementation works but has some duplication. Refactor it
    for clarity. Run tests after every change to make sure nothing
    breaks.

Większość projektów ma pokrycie testowe rozłożone nierówno. Krytyczna logika biznesowa może mieć 30% pokrycia, podczas gdy funkcja pomocnicza ma 100%. Claude potrafi znaleźć i wypełnić te luki.

Gdy musisz poprawić pokrycie konkretnego modułu:

Read src/services/payment.service.ts and the coverage report
for it. Show me which lines and branches are not covered.
Then write tests that cover the uncovered paths. Focus on:
- Error handling branches (catch blocks, validation failures)
- Conditional logic that is only tested for the true case
- Async paths where the promise rejects

Skonfiguruj hooki, aby Claude automatycznie weryfikował testy po każdej zmianie:

.claude/settings.json
{
"hooks": {
"PostToolUse": [
{
"matcher": "Edit|Write",
"command": "npm test -- --run --reporter=verbose 2>&1 | tail -20"
}
]
}
}

Z tym hookiem każda edycja pliku wyzwala uruchomienie testów. Claude widzi wynik testów natychmiast i może naprawić problemy bez twojego pytania.

Write unit tests for src/services/order.service.ts.
Mock all dependencies (database, email service, payment gateway).
Use our existing mock factory in tests/utils/mocks.ts.
Test each public method with:
- Valid input (happy path)
- Invalid input (validation errors)
- Dependency failure (database down, payment rejected)
- Edge cases (empty arrays, null values, boundary numbers)
Write integration tests for src/routes/order.routes.ts.
Use a test database (our test config creates an in-memory SQLite).
Test each endpoint:
- POST /orders - successful creation, validation errors, auth required
- GET /orders/:id - found, not found, wrong user (403)
- PATCH /orders/:id/status - valid transitions, invalid transitions
- DELETE /orders/:id - owner can delete, non-owner gets 403
Use supertest and follow the patterns in tests/routes/user.routes.test.ts.
Write an E2E test that covers the complete order flow:
1. Create a user and log in
2. Add items to cart
3. Submit an order
4. Verify the order appears in the user's order list
5. Verify the inventory was decremented
6. Verify the confirmation email was queued
Use Playwright and follow our existing E2E patterns in
tests/e2e/auth-flow.test.ts.

Do automatycznej poprawy pokrycia w CI użyj trybu headless:

Okno terminala
# Generate tests for files that changed in this PR
git diff --name-only main...HEAD -- 'src/**/*.ts' | \
while read file; do
test_file="${file/src/tests}"
test_file="${test_file/.ts/.test.ts}"
if [ ! -f "$test_file" ]; then
claude -p "Read $file and generate comprehensive tests.
Follow the patterns in our existing test files.
Save to $test_file." --output-format json
fi
done

Dla bardziej celowanego podejścia:

Okno terminala
# Generate tests for uncovered code
claude -p "Run npm test -- --coverage --json. Find all source
files with less than 80% line coverage. For each one, generate
tests that bring coverage above 80%. Match existing test patterns.
Run the tests to verify they pass." --output-format json

Dobre testy potrzebują dobrych danych testowych. Poproś Claude o wygenerowanie fixture’ów pasujących do twojego schematu:

Read our Prisma schema and the existing fixtures in tests/fixtures/.
Generate test fixtures for the organization module:
1. A factory function createTestOrganization() that generates
a valid organization with sensible defaults
2. A factory function createTestOrgMember() that creates a user
with membership in an organization
3. Edge case fixtures: org with maximum members, org with expired
trial, org with special characters in the name
Follow the same factory pattern as createTestUser() in
tests/fixtures/user.fixtures.ts.

Wygenerowane testy są zbyt płytkie. Claude czasami generuje testy pokrywające tylko ścieżkę sukcesu. Bądź konkretny: “Include at least one test for each error path in the source code. Count the catch blocks and if statements — each one needs a test.”

Testy są kruche i łamią się przy drobnych zmianach. Testy sprawdzają zbyt wiele szczegółów implementacji. Powiedz Claude: “Test behavior, not implementation. Assert on return values and side effects, not on internal method calls or the number of times a function was invoked.”

Mocki są skonfigurowane nieprawidłowo. Dzieje się tak, gdy Claude nie przeczytał twoich istniejących wzorców mockowania. Zawsze wskazuj go na istniejący plik testowy z działającymi mockami przed generowaniem nowych testów: “Read the mock setup in tests/services/user.service.test.ts. Use the exact same approach for mocking the database and external services.”

Testy przechodzą pojedynczo, ale nie razem. Współdzielony mutowalny stan między testami. Powiedz Claude: “Each test must be independent. Check for shared variables that are modified in tests. Use beforeEach to reset state. If using a test database, isolate with transactions that roll back.”

Raport pokrycia jest mylący. Wysokie pokrycie liniowe nie oznacza dobrych testów. Po wygenerowaniu testów dla pokrycia przejrzyj je: “For each test you generated, explain what behavior it verifies. If a test only exercises a line without asserting meaningful behavior, rewrite it.”

Twój zestaw testów jest kompleksowy, a luki w pokryciu wypełnione. Gdy te testy wychwytują błąd, potrzebujesz systematycznego workflow debugowania, aby prześledzić przyczynę.