Rzemiosło · The Craft
Czym jest The CraftPoziomyJak zacząćRozdziały Szukaj Pobierz PLEN
Level 2 · Technika ~4 min czytania

W jednym zdaniu: Każdą zmianę się weryfikuje, nie deklaruje — testy i realne sprawdzenie zamiast „chyba działa”.

Ten rozdział po ludzku

Rozdział rozróżnia dwie rzeczy, które łatwo pomylić:

  • Testy — automatyczna siatka bezpieczeństwa, którą uruchamiasz wielokrotnie; pilnuje, żeby jutrzejsza zmiana czegoś nie zepsuła.
  • Weryfikacja — dowód, że ta konkretna zmiana robi to, co miała, zobaczony na własne oczy, a nie założony.

Obie są obowiązkowe. To, że testy przechodzą, nie znaczy jeszcze, że funkcja działa w przeglądarce; a ręczne kliknięcie bez testów nie chroni przed regresją za tydzień.

Sedno — „weryfikuj, nie deklaruj”: zamiast pisać „działa”, pokazujesz dowód (kod odpowiedzi HTTP, liczbę z bazy, zrzut ekranu). I raportujesz uczciwie: jeśli testy padły, mówisz to z wynikiem, nie chowasz.

Domyślnym trybem pracy jest TDD — Test-Driven Development: najpierw piszesz test (czego oczekujesz), potem kod, który go spełnia. Test zostaje w projekcie i pilnuje, że zmiana niczego nie zepsuła — dowód zamiast „chyba działa”.: najpierw piszesz test, który opisuje, czego oczekujesz, i pada (czerwony); potem najmniejszą zmianą doprowadzasz go do zielonego. Twarda reguła: commit, który zmienia zachowanie, a nie niesie testu, jest niekompletny.

Strażnik dowodzi się na incydencie, nie na fikstrze. Kontrolę pisaną po awarii (żeby dany błąd nie wrócił) najpierw odpal na prawdziwych danych tej awarii — potwierdź, że łapie. Fikstura pisana tą samą głową, która popełniła błąd, potrafi go przeoczyć; strażnik, który przepuszcza własny przypadek, jest gorszy niż jego brak — zamienia otwarte pytanie w fałszywy spokój.

Przykład piramidy testów: dużo szybkich testów jednostkowych (sprawdzają pojedyncze funkcje) u podstawy, a mało e2e (klikają całą ścieżkę w przeglądarce) u góry — bo te drugie są wolne i kruche.

Doczytaj: testowanie oprogramowania · TDD (test-driven development) · piramida testów (Martin Fowler).

03 — Testowanie i weryfikacja

Przykazanie III: Weryfikuj, nie deklaruj.

Dwie różne rzeczy, często mylone:

  • Testy — zautomatyzowana siatka bezpieczeństwa, którą uruchamiasz wielokrotnie.
  • Weryfikacja — dowód, że ta konkretna zmiana robi to, co miała, zaobserwowany, nie założony.

Obie są obowiązkowe. Test, który przechodzi, nie znaczy, że feature działa w przeglądarce; ręczna weryfikacja bez testów nie chroni przed regresją jutro.

Piramida (z projektu referencyjnego)

PoziomNarzędzieCo pokrywaKiedy
Unitpytest / Jestlogika czysta (normalizer, matcher, helpery, walidatory)co commit
IntegrationSupertest (HTTP)trasy, auth-guardy, API — Umówiony sposób, w jaki dwa programy gadają ze sobą — jeden prosi, drugi odpowiada w ustalonym formacie. Przez API Twoja aplikacja łączy się z cudzymi usługami (płatności, mapy, AI). Klucz API traktuj jak hasło. JSONco commit
E2E / browserPlaywrightrealne ścieżki w przeglądarce, na osobnym porcieprzed deployem / przy UI
Smokeskrypt (smoke.ps1)„czy serwer wstaje i N tras zwraca poprawnie”po restarcie / przed/po deployu

Reguły, które się sprawdziły:

  • Uruchamiaj testy przed commitem ścieżki krytycznej.
  • Jest z --runInBand, gdy serwer dev/preview chodzi (konflikt portów/DB).
  • Smoke test — Szybki test „czy w ogóle działa” zaraz po wdrożeniu — sprawdza najważniejsze ścieżki (np. logowanie). Łapie katastrofy w 30 sekund, zanim zobaczy je użytkownik. Tani sposób na spokojny sen po deployu. ma markery — sprawdza, że wyrenderowała się właściwa strona (np. price-gate dla anonima, nie tylko HTTP 200).
  • Testy auth z obu stron — anonim odbity do logowania i zalogowany widzi treść.

„Weryfikuj, nie deklaruj” — w praktyce

Po zmianie obserwowalnej w aplikacji pokaż dowód, nie proś usera, żeby sam sprawdził:

  • kod HTTP / redirect_url (curl -o /dev/null -w),
  • fragment HTML potwierdzający (np. og:image wskazuje na właściwy plik),
  • liczby z bazy (ile kont, ile cen, integrity_check: ok),
  • screenshot przy zmianach wizualnych.

Po deployu — smoke test na żywym serwerze (przez localhost za flagą maintenance), a gdy znajdziesz błąd w oknie — napraw go w oknie, jeśli to trywialne i bezpieczne (w projekcie referencyjnym tak złapaliśmy i naprawiliśmy zastane ERR_HTTP_HEADERS_SENT na /mapa).

Raport ma być uczciwy

  • Testy padają → powiedz to z outputem, nie chowaj.
  • Coś pominięto → powiedz, że pominięto.
  • Gdy 2 testy padają z dryfu danych (np. cohort-fixture 85% vs 85%), a nie z regresji — odróżnij to jawnie i nie blokuj nimi deployu, ale zaproponuj follow-up (regeneracja fixture’ów).
  • „Zrobione i zweryfikowane” mów dopiero, gdy naprawdę zweryfikowane — bez hedgingu, ale i bez ściemy.

Liczby weryfikuj u źródła

Nie ufaj liczbie z pamięci ani z dokumentacji — odpytaj bazę/test. Dokumentacja się starzeje; SELECT COUNT(*) nie kłamie. (Przykazanie X: „liczby weryfikuj”.)

Web — sprawdzony zestaw kontroli

Dla stron/projektów webowych ten zestaw testów już się w praktyce sprawdził (typowy zestaw to kilkadziesiąt metod i kilkaset subtestów) — przenoś go domyślnie:

  • SEO meta (title/description per strona), canonical + hreflang — Oznaczenie, które mówi wyszukiwarce, w jakim języku jest strona i gdzie są jej wersje w innych językach. Bez tego wielojęzyczna strona myli Google — wersje językowe „walczą” o tę samą frazę., JSON-LD — Dane strukturalne: niewidoczny dla człowieka opis strony, który czyta wyszukiwarka (np. FAQ, autor, breadcrumbs). Otwiera „rich snippets” w Google — bogatsze wyniki, wyższy CTR..
  • Dostępność: kontrast tokenów kolorów, nawigacja klawiaturą, sensowne alt/aria.
  • Parytet EN↔PL (i każdej pary językowej): brakujący klucz/strona w jednym języku = test, który pada.
  • Martwe linki wewnętrzne — żaden link w buildzie nie prowadzi w pustkę.
  • Spójność motywu (theme cookie / dark-light) i poprawność builda (każda strona się wyrenderowała).

Anty-wzorce

  • 🚫 „Powinno działać” jako konkluzja.
  • 🚫 Uruchomienie tylko jednego testu i ogłoszenie „suite zielony”.
  • 🚫 Pominięcie smoke testu po deployu, bo „przecież testy przeszły”.
  • 🚫 Mylenie „kod się kompiluje” z „feature działa dla użytkownika”.

TDD — domyślny tryb pracy

Test najpierw, nie po fakcie. Cykl:

  1. Czerwony — napisz test, który opisuje oczekiwane zachowanie i pada.
  2. Zielony — najmniejsza zmiana w kodzie, aż test przechodzi.
  3. Refactor — posprzątaj przy zielonym suite (→ 02).

Bug naprawiasz tak samo: najpierw test odtwarzający błąd, potem fix — test zostaje jako regresja, żeby błąd nie wrócił.

Każda zmiana w commicie niesie test. Twarda reguła: commit, który zmienia zachowanie, a nie dodaje/zmienia testu, jest niekompletny. Nowy Endpoint — Pojedynczy „adres” w API, pod który wysyłasz zapytanie po konkretną rzecz (np. listę zamówień). Aplikacje rozmawiają przez endpointy — jeden endpoint = jedna funkcja, którą udostępniasz. → test trasy; nowy próg/fallback → test progu; naprawiony bug → test regresji. „Dodam testy później” = grzech (koniec nie nadchodzi). → 00, 08

Guard dowodzi incydent, nie fixture

Check napisany po awarii musi zostać odtworzony na realnych danych tej awarii, zanim mu zaufasz. Fixture pisze ta sama głowa, która napisała buga, więc dziedziczy jej martwe pole: w projekcie referencyjnym check świeżości danych przeszedł dziewięć zielonych testów jednostkowych, po czym nie wykrył tej właśnie awarii, dla której powstał — porównanie było > tam, gdzie miało być >=, a zamrożone źródła stały dokładnie na progu. Guard, który przepuszcza własny przypadek referencyjny, jest gorszy niż jego brak: zamienia otwarte pytanie w fałszywy spokój. Wyceluj go w produkcję (albo snapshot), potwierdź, że odpala, i dopiero wtedy zamroź próg w fixture — z jawnym testem na samym progu.

  • Testuj kontrakt, nie implementację — inaczej refactor kruszy testy bez realnej regresji.
  • Suite szybki i deterministyczny — wolny lub migający suite przestaje być uruchamiany; izoluj I/O, ustaw seedy, --runInBand przy współdzielonym porcie/DB.
  • CI bramkuje — czerwone testy blokują merge i deploy; testy ścieżki krytycznej odpalasz przed commitem.

Treść doktryny prowadzimy po polsku.