Testowanie za pomocą plików wzorcowych
Spec: ISO/IEC/IEEE 29119-4 ISO/IEC/IEEE 29119-4 Spec: ISO/IEC 25010 ISO/IEC 25010 Evidence: Test-backed
W skrócie
Dział zatytułowany „W skrócie”Plik wzorcowy to zapisany ślad mówiący: „tak wygląda poprawny wynik”, z którym test porównuje rezultat przy każdym uruchomieniu. NextPDF używa wzorców do wychwytywania zmian, których nikt nie zamierzał wprowadzić: inaczej skompresowanego strumienia, przesuniętego akapitu albo współrzędnej, która zaczęła dryfować. Ta strona wyjaśnia, jak to działa i jak wzorzec pozostaje wiarygodny, zamiast stać się nieaktualnym odniesieniem, którego nikt nie czyta.
Dlaczego to ma znaczenie
Dział zatytułowany „Dlaczego to ma znaczenie”Generowanie plików PDF to długi potok z wieloma miejscami, w których może dojść do cichego dryfu. Refaktoryzacja, która „niczego nie zmienia”, może po cichu zmienić kolejność operatorów, zmodyfikować macierz przekształcenia lub przesunąć komórkę tabeli o niewielką wartość. Testy jednostkowe rzadko to wychwytują: sprawdzają wartość, którą postanowiono skontrolować, a nie tysiące bajtów, których nie objęto kontrolą. Techniki oparte na strukturze i na specyfikacji wykrywają różne błędy, a żadna z nich nie zawiera się w drugiej (ISO/IEC/IEEE 29119-4, Annex A). Plik wzorcowy to specyfikacja przez przykład, która blokuje cały wynik, a nie pojedyncze założenie.
Ryzyko działa w obie strony. Zbyt rygorystyczny wzorzec zawodzi przy każdej nieszkodliwej zmianie i bywa bezrefleksyjnie ponownie zatwierdzany, aż przestaje cokolwiek dowodzić. Zbyt luźny wzorzec przepuszcza prawdziwe regresje. Trafne wyważenie tej równowagi to cała sztuka.
W skrócie najważniejsze
Dział zatytułowany „W skrócie najważniejsze”- Tak zwany plik wzorcowy to zablokowany wynik referencyjny, wygenerowany na podstawie sprawdzonego, poprawnego zachowania silnika i zapisany w repozytorium.
- Test wzorcowy ponownie generuje wynik i porównuje go z zablokowanym odniesieniem; każda różnica oznacza niezaliczenie testu i wymaga decyzji człowieka.
- NextPDF porównuje na poziomie istotnym, ale stabilnym: wyodrębniony tekst i znormalizowane operatory strukturalne, a nie surowe bajty, ponieważ surowe bajty niosą szum (znaczniki czasu, kolejność podzbiorów, kompresję), który nie jest regresją.
- Aktualizacja wzorca to świadoma, sprawdzona czynność ukryta za jawnym przełącznikiem
GOLDEN_UPDATE— nigdy automatyczne „zaakceptuj cokolwiek się zmieniło”. - Testowanie wzorcowe różni się od testowania migawkowego i charakteryzującego jedną decydującą cechą: wzorzec nigdy nie jest aktualizowany automatycznie.
Jak podchodzi do tego NextPDF
Dział zatytułowany „Jak podchodzi do tego NextPDF”Infrastruktura wzorcowa silnika stosuje jawne dwuwarstwowe porównanie różnic zamiast porównywania bajtów:
- Generate Render the fixture input through the current engine.
- Layer 1 — text Extract human-readable text from the content stream; diff against the text golden. Catches dropped or reordered content and encoding regressions.
- Layer 2 — structure Extract ordered PDF operators, normalise coordinates to a fixed precision, diff against the operator golden. Catches layout shifts and broken structure.
- Decide Any diff fails the test; a human judges whether it is a regression or an intended change.
To, czego celowo nie porównuje, jest równie ważne jak to, co porównuje. Surowy wynik bajtowy jest wykluczony, ponieważ znaczniki czasu, kolejność podzbiorów czcionek i kompresja strumienia czynią go kruchym, ale nie bardziej poprawnym. Porównywanie obrazów na poziomie pikseli jest wykluczone z tej warstwy, ponieważ wymaga zewnętrznego mechanizmu renderującego i wprowadza zmienność środowiska. Współrzędne zmiennoprzecinkowe są normalizowane do stałej precyzji, aby bezsensowny szum zaokrągleń nie udawał regresji. Na tym polega różnica między wzorcem, który testuje zachowanie, a takim, który testuje przejściowy szum środowiskowy.
Ten wybór decyduje również o profilu powtarzalności tej strony: strukturalnym. NextPDF dokumentuje trzy profile — bitowy (odtwarzane są dokładne bajty), strukturalny (odtwarzane są graf obiektów i sekwencja operatorów, z dopuszczeniem nieszkodliwej zmienności na poziomie bajtów) oraz semantyczny (odtwarzane jest znaczenie). Testy wzorcowe na tej warstwie z założenia potwierdzają profil strukturalny. Dlatego ich odniesienia przetrwają podbicie wersji biblioteki kompresji, ale nadal zasygnalizują niepowodzenie przy przesuniętej tabeli.
Co mówią dowody
Dział zatytułowany „Co mówią dowody”Evidence: Test-backed Dwuwarstwowe porównanie (wyodrębnienie tekstu, a następnie znormalizowane porównanie operatorów strukturalnych) to własna, udokumentowana metodyka wzorcowa silnika, w której porównywanie surowych bajtów, różnic obrazu i dokładnych wartości zmiennoprzecinkowych pozostaje jawnie poza zakresem z podanych wyżej powodów. Zestaw testów wzorcowych to zadeklarowany, osobno uruchamialny zestaw testów, odrębny od zestawów migawkowych i charakteryzujących.
Evidence: Test-backed Mechanizm uczciwości jest konkretny:
odniesienia wzorcowe to generowane artefakty, a nie pisane ręcznie. Nadpisywanie
ich jest ograniczone jawnym przełącznikiem środowiskowym GOLDEN_UPDATE udokumentowanym
jako rzadka, zawsze sprawdzana operacja. Dla kontrastu testy migawkowe w
silniku są regenerowane przy pierwszym uruchomieniu, a dryf potwierdza się za pomocą flagi aktualizacji. Z kolei
testy charakteryzujące blokują dotychczasowe zachowanie, nie twierdząc, że jest ono
poprawne. Te trzy są celowo różnymi narzędziami.
Evidence: Standard-backed Wzorzec to specyfikacja przez przykład. Spec: ISO/IEC/IEEE 29119-4, Annex A ISO/IEC/IEEE 29119-4 Annex A zauważa, że techniki oparte na specyfikacji i na strukturze wychwytują różne klasy błędów oraz że strategia powinna je łączyć. Dlatego wzorce funkcjonują obok, a nie zamiast, testów jednostkowych i strukturalnych w piramidzie testów.
Praktyczny przykład
Dział zatytułowany „Praktyczny przykład”Test wzorcowy jest mechanicznie prosty; cała dyscyplina tkwi w otaczającym go przepływie pracy:
<?php
declare(strict_types=1);
// 1. The fixture: a fixed HTML input committed next to the test.// tests/Golden/fixtures/html-inputs/002-basic-table.html
// 2. The pinned references, generated once from known-good behaviour:// 002-basic-table.text.golden (Layer 1 — extracted text)// 002-basic-table.operators.golden (Layer 2 — normalised operators)
// 3. The run compares; ANY difference fails:// vendor/bin/phpunit --testsuite Golden
// 4. An intended behaviour change is the ONLY time references move,// and it is explicit and reviewed — never automatic:// GOLDEN_UPDATE=1 vendor/bin/phpunit --testsuite Golden//// The regenerated *.golden files land in the diff of the same change// that altered behaviour, so a reviewer sees the output delta next to// the code delta and signs off on both together.Tym przykładem jest sam proces. Kod testu jedynie porównuje różnice. Wiarygodność wzorca polega na tym, że zmienione odniesienie jest sprawdzane jako wynik w tej samej zmianie, która zmodyfikowała silnik.
Częste nieporozumienie
Dział zatytułowany „Częste nieporozumienie”Najczęstszym błędem jest traktowanie testowania wzorcowego jako testowania bajt po bajcie. Wzorce NextPDF to nie bajty pliku — to jego wyodrębniony tekst i znormalizowane operatory strukturalne. Sprawdzanie surowych bajtów zawiodłoby przy nowej wersji zlib, innym znaczniku podzbioru lub ponownie wygenerowanym znaczniku czasu, z których żaden nie jest regresją. W ciągu tygodnia test zostałby przez ponowne zatwierdzanie sprowadzony do bezużyteczności. (Tam, gdzie dokładne bajty rzeczywiście muszą się odtwarzać, mamy do czynienia z osobnym, bardziej rygorystycznym profilem powtarzalności bitowym, a nie z wzorcem.)
Drugim błędem jest założenie, że zielony zestaw testów wzorcowych dowodzi poprawności. Dowodzi braku zmiany. Wzorzec wygenerowany z błędnego wyniku wiernie chroni ten błąd. Wzorce chronią przed regresją względem sprawdzonej, poprawnej linii bazowej; nie przesądzają, że sama linia bazowa była poprawna. Do tego służą warstwy jednostkowa, strukturalna i zgodności.
Ograniczenia i granice
Dział zatytułowany „Ograniczenia i granice”Test wzorcowy odpowiada na dokładnie jedno pytanie: czy wynik zmienił się względem zablokowanego odniesienia. Nie mówi, czy odniesienie kiedykolwiek było poprawne. Nie mierzy też wydajności, zgodności ani bezpieczeństwa. To inne warstwy. Rozmiar korpusu danych testowych, wskaźnik zaliczeń zestawu testów oraz wszelkie wartości pokrycia to żywe sygnały jakości generowane z artefaktów ciągłej integracji i publikowane wraz z kompilacją. Celowo nie podajemy ich tutaj, gdzie mogłyby się zdezaktualizować.
Dokładny układ katalogów, wewnętrzne mechanizmy komparatora oraz przełącznik aktualizacji należą do infrastruktury testowej silnika i mogą ewoluować. W razie jakiejkolwiek rozbieżności z tym wyjaśnieniem źródłem rozstrzygającym jest konfiguracja testów. Ta strona nie wypowiada się na temat narzędzi migawkowych ani wzorcowych żadnej innej biblioteki.
Powiązana dokumentacja
Dział zatytułowany „Powiązana dokumentacja”- Piramida testów NextPDF — gdzie warstwa wzorcowa mieści się wśród pięciu warstw i co jako jedyna dowodzi.
- Testowanie mutacyjne — wyjaśnienie — jak NextPDF sprawdza, czy jego testy, w tym wzorce, faktycznie wykrywają usterki.
- Ścisłe typowanie wszędzie — analiza statyczna, która usuwa pewną klasę defektów, zanim uruchomi się jakikolwiek wzorzec.
Słowniczek
Dział zatytułowany „Słowniczek”- Plik wzorcowy — zablokowany wynik referencyjny, wygenerowany na podstawie sprawdzonego, poprawnego zachowania silnika i zatwierdzony; test porównuje z nim różnice przy każdym uruchomieniu. Nigdy nie aktualizowany automatycznie.
- Dwuwarstwowe porównanie różnic — porównanie wzorcowe NextPDF: wyodrębniony tekst (warstwa 1) oraz znormalizowane operatory strukturalne (warstwa 2), zamiast surowych bajtów.
- Test migawkowy — pokrewna, lecz odrębna technika, w której odniesienie jest regenerowane przy pierwszym uruchomieniu, a dryf potwierdza się za pomocą flagi aktualizacji.
- Test charakteryzujący — test, który blokuje istniejące zachowanie bez potwierdzania, że jest ono poprawne, zwykle po to, aby uczynić refaktoryzację bezpieczną.
- Profil powtarzalności — poziom, na którym wynik musi się odtwarzać: bitowy (dokładne bajty), strukturalny (graf obiektów i sekwencja operatorów, z dopuszczeniem nieszkodliwej zmienności bajtów) lub semantyczny (znaczenie). Testy wzorcowe potwierdzają tutaj profil strukturalny.
GOLDEN_UPDATE— jawny przełącznik środowiskowy, który autoryzuje nadpisywanie odniesień wzorcowych; rzadka, sprawdzana operacja.