Testy, które dają wartość
100% coverage to kłamliwa meta. Oto jak budować piramidę testów która realnie chroni.
Pułapka 100% coverage
Pokrycie procentowe mierzy linie wykonane, nie zachowanie zweryfikowane. Możesz mieć 100% coverage a zero asercji — test "przechodzi" bo kod się wykonał.
Coverage odpowiada na pytanie "co nie zostało przetestowane". Nigdy na "czy jest dobrze".
Piramida testów
/\
/E2E\ <- malo, wolne, krytyczne ścieżki
/_____\
/integracyjne\ <- granice modułów, bazy, API
/___________\
/ jednostkowe \ <- dużo, szybkie, logika biznesowa
/_________________\
- Jednostkowe (70-80%) — czysta logika, nano-sekundy, zero I/O.
- Integracyjne (15-25%) — moduł × baza × zewnętrzny mock.
- E2E (2-5%) — tylko najważniejszy flow (checkout, login).
Co warto testować
Priorytet 1: logika biznesowa z rozgałęzieniami. To gdzie są błędy.
Priorytet 2: granice — parsowanie wejścia, walidacja, kontrakty API.
Nie warto: gettery/settery, czyste pass-throughy, UI snapshoty bez asercji semantycznych.
Testy jako dokumentacja
Dobrze nazwany test (test_refund_rejected_when_order_shipped) to żywa specyfikacja. Jak nowy dev pyta "co się dzieje gdy...", pokazujesz mu test, nie Confluence.
Praktyka: characterisation + mutation
- Characterisation (Jester/Crater): sprawdz czy testy WYKRYWAJĄ błędy — mutuj kod, patrz czy testy failą. Jeśli mutacja przechodzi zielono → test niczego nie chroni.
- To lepszy wskaźnik niż coverage.
Podsumowanie
Nie gon za procentami. Buduj piramidę: dużo szybkich jednostkowych wokół logiki, mało wolnych E2E na krytycznych ścieżkach. Jeden test który łapie regresję warty więcej niż dziesięć "assert true".