tdd: red-green-refactor, ale z regułami które robią różnicę
Czwarty krok z zalecanej kolejności README: implementacja. Skill zaczyna od zdania, które warto zapamiętać dosłownie: "TDD is the red → green loop. This skill is the reference that makes that loop produce tests worth keeping." Sam red-green-refactor znasz pewnie już skądinąd — ta lekcja skupia się na regułach, które odróżniają test wart utrzymania od testu, który tylko wygląda jak TDD.
Polecane źródło
Lokalne pliki .agents/skills/tdd/{SKILL,tests}.md w tym repo.
Rozpoznawalny znak złego testu: psuje się przy refaktorze, mimo że zachowanie się nie zmieniło. Dobry test przeżywa refaktor, bo w ogóle nie wie, jak coś jest zaimplementowane wewnątrz — tylko co jest widoczne z zewnątrz.
Seam: gdzie w ogóle wolno testować
Seam to publiczna granica, przy której obserwujesz zachowanie, nie sięgając do środka. Reguła jest twarda: testujesz tylko przy wcześniej uzgodnionych seamach. Zanim padnie choć jeden test, skill ma zapytać: "What's the public interface, and which seams should we test?" — i dopiero po Twojej odpowiedzi zaczyna pisać.
Kluczowy wniosek: nie da się przetestować wszystkiego, więc uzgadnianie seamów z góry to sposób, żeby wysiłek testowy trafiał w krytyczne ścieżki i złożoną logikę, a nie w każdy możliwy przypadek brzegowy. Test napisany przy nieuzgodnionym seamie jest z definicji błędem procesu, niezależnie od tego, czy przechodzi.
Trzy anti-patterny
Anti-pattern
Rozpoznasz po
Implementation-coupled
mockuje wewnętrzne komponenty, testuje prywatne metody, albo sprawdza przez boczne wejście (query do bazy zamiast przez interfejs)
Tautologiczny
oczekiwana wartość liczona tym samym sposobem co kod (expect(calculateTotal(items)).toBe(items.reduce(...))) — test przechodzi z definicji
Horizontal slicing
najpierw wszystkie testy, potem cała implementacja — testujesz wyobrażone zachowanie, nie prawdziwe
Tautologiczny test naprawiasz, licząc oczekiwaną wartość niezależnie: expect(calculateTotal([{price:10},{price:5}])).toBe(15) zamiast przepisywać wzór sumowania drugi raz. Horizontal slicing to dokładnie odwrotność vertical slices z Lekcji 15 — tu też obowiązuje zasada tracer bullet: jeden test → jedna minimalna implementacja → powtórz, każdy cykl reagujący na to, czego nauczył poprzedni.
Trzy zasady pętli
Red przed green — najpierw failing test, potem tylko tyle kodu, żeby przeszedł. Bez wyprzedzania przyszłych testów, bez spekulatywnych funkcji.
Jeden plaster naraz — jeden seam, jeden test, jedna minimalna implementacja na cykl.
Refaktoring NIE jest częścią pętli — należy do etapu review (skill code-review, dwie lekcje dalej), nie do cyklu red→green.
Zadanie praktyczne — jeden cykl, z prawdziwym uzgodnieniem seamów
W swoim prawdziwym projekcie, na jednym z issues z Lekcji 15, wpisz /tdd:
Sprawdź: czy Claude faktycznie zapytał o publiczny interfejs i seamy, zanim napisał pierwszy test?
Obserwuj tempo: jeden test, potem minimalna implementacja, potem kolejny test — czy faktycznie tak małymi krokami?
Po zielonym teście: czy ktoś (Claude albo Ty) próbuje "przy okazji" refaktorować w tym samym cyklu? Jeśli tak — to sygnał złamania zasady 3.
Sprawdź się
1. Co skill ma zrobić PRZED napisaniem pierwszego testu w cyklu TDD?
Zasada jest twarda: żaden test nie powstaje przy nieuzgodnionym seamie. Skill pyta "what's the public interface, and which seams should we test?" zanim napisze cokolwiek.
2. Test przechodzi zawsze, bo oczekiwana wartość jest liczona tym samym wzorem co kod produkcyjny. Jaki to anti-pattern?
Test tautologiczny przechodzi z konstrukcji, bo oczekiwana wartość jest przeliczana tak samo jak w kodzie — musi pochodzić z niezależnego źródła prawdy (literał, przykład ze specyfikacji).
3. Test sprawdza dane bezpośrednim zapytaniem do bazy zamiast przez publiczny interfejs funkcji. Który to anti-pattern?
Weryfikacja przez query do bazy zamiast przez interfejs (np. getUser) to klasyczny przykład implementation-coupled — test wie za dużo o tym, jak coś jest zaimplementowane wewnątrz.
4. Napisano naraz wszystkie testy dla całej funkcji, a implementację zaczęto dopiero potem. Co to narusza?
To horizontal slicing — bulk testów napisanych z góry weryfikuje wyobrażone zachowanie. Zasada mówi: jeden seam, jeden test, jedna minimalna implementacja na cykl.
5. Test właśnie zzielenił się (green). Gdzie należy refaktoring tego kodu, według tego skilla?
Skill wprost oddziela pętlę implementacyjną od refaktoringu: "Refactoring is not part of the loop... it belongs to the review stage" — czyli do code-review, kolejnego kroku w cyklu.
Coś niejasne? Zapytaj mnie wprost — mogę pomóc ocenić, czy konkretny test z Twojego projektu jest implementation-coupled, czy faktycznie testuje przez seam.