NextPDF 的測試金字塔
Spec: ISO/IEC/IEEE 29119-4 ISO/IEC/IEEE 29119-4 Spec: ISO/IEC 25010 ISO/IEC 25010 Evidence: Test-backed PHPStan: Level 10
NextPDF 不只依靠一種測試。它有五個層級,每一層都回答關於這個引擎的不同問題。原因在於,一份 PDF 可以通過單元測試,卻仍然是磁碟上一個結構損壞的檔案。本頁列出這五個層級,以及每一層各自負責證明什麼。
為什麼這很重要
標題為「為什麼這很重要」的區段PDF 引擎的失敗面非常廣。同一條程式碼路徑可以在函式層面正確、在位元組串流層面也正確,卻仍然產生一份符合規範的閱讀器會拒絕的檔案。它也可能產生一份只在換頁處出現細微算繪錯誤的檔案。如果只用單一粒度測試這個引擎,你得到的信心也只停留在那個粒度,不能再多。
標準文獻對此說得很清楚。以規格為基礎與以結構為基礎的測試設計技術彼此並不相關,因此建議測試策略採用不只一項準則,至少包含一項功能性與一項結構性(ISO/IEC/IEEE 29119-4, Annex A)。單一層級並不是良好策略的縮小版;它是一種不同的策略,而且並不完整。
精簡版
標題為「精簡版」的區段NextPDF 的測試由底部到頂端編排為五個層級:
- 單元(Unit)——單一類別或函式,獨立隔離。寬闊的底部。
- 整合(Integration)——跨模組邊界協作的多個單元。
- 結構(Structural)——所產生的 PDF 物件圖、交叉參照表與尾段格式正確且符合規範。
- 視覺(Visual)——算繪後的頁面在宣告的容差範圍內與一份核准的參照相符。
- 黃金檔(Golden)——釘定的端到端固定樣本,用以捕捉最終輸出中的非預期偏移。頂端。
每一層都證明其下層無法證明的事。沒有一層是裝飾性的。金字塔的形狀說的是數量——大量廉價的單元測試、較少昂貴的端到端測試——而非重要性。
NextPDF 如何處理這件事
標題為「NextPDF 如何處理這件事」的區段這些層級是實際存在的,而非空泛願景。這個程式庫的 PHPUnit 設定將每一層都宣告為一個具名測試套件,並與一個目錄一對一對應。因此,每個層級都是你可以讓測試執行器指向的目標,而不是投影片上的標籤。資深工程師熟悉的套件包括 Unit、Integration、Golden、Snapshot、Reproducibility、Conformance、Standards 以及 Performance,每一個都有自己的執行設定(隔離方式、時間預算,以及是否在持續整合中預設執行)。
這種區隔是刻意設計的。快速的底層(Unit)會在每次變更時執行,每個測試的預算為一秒。較慢、對環境敏感的層級——視覺算繪、完整一致性、效能——則採選擇性加入或每夜執行。這讓常見路徑保持快速且具決定性,同時不放棄更深入的檢查。嚴格型別支撐著整個技術堆疊。這個引擎以 Spec: PHPStan, Level 10 PHPStan Level 10 進行分析,錯誤預算鎖定為零,因此一大類缺陷根本不會走到測試這一步。
- Tier 1 of 5 Unit Isolated behaviour of a single class or function; the broad base.
- Tier 2 of 5 Integration Collaborating units across a module boundary.
- Tier 3 of 5 Structural The emitted PDF object/xref structure is well-formed and conformant.
- Tier 4 of 5 Visual Rendered output matches an approved reference within tolerance.
- Tier 5 of 5 Golden End-to-end byte/lossless fixtures pinned as the contract; the apex.
證據怎麼說
標題為「證據怎麼說」的區段Evidence: Test-backed 這五個套件在引擎的設定中以宣告的 PHPUnit 測試套件形式存在,每一個都綁定到自己的目錄與執行設定。本頁使用的層級術語,與測試基礎設施使用的術語相同。
Evidence: Standard-backed 採用不只一個層級的理由建立在 Spec: ISO/IEC/IEEE 29119-4, Annex A ISO/IEC/IEEE 29119-4 Annex A : 覆蓋準則不一定彼此相關,因此建議策略結合功能性與結構性技術。關鍵在於,同一份附錄指出,覆蓋準則之間的涵蓋(subsumes)排序並未顯示出它們揭露缺陷的能力——測試有效性 (ISO/IEC/IEEE 29119-4, §C.2.4)。「更多覆蓋率」並不等同於 「更好的測試」這項主張。
Evidence: Standard-backed 選擇要證明哪些性質 ,對應到 Spec: ISO/IEC 25010 ISO/IEC 25010 的產品品質特性:功能正確性(單元、整合),以及使一份 PDF 在下游真正可用的檔案層級性質 (結構、視覺、黃金檔)。該品質模型明確指出,不同的特性在不同的使用情境中各有其重要性。
實際範例
標題為「實際範例」的區段引擎自己的指令稿可以直接指定這些層級。對單一格式器的變更在底層驗證。對文件外觀(facade)的變更則會跨多個層級驗證:
<?php
declare(strict_types=1);
// Tier 1 — Unit: one unit, isolated, fast.// composer test:unit → phpunit --testsuite Unit
// Tier 2 — Integration: collaborating units across a boundary.// composer test:integration → phpunit --testsuite Integration
// Tier 3 — Structural: the emitted PDF object graph is well-formed.// vendor/bin/phpunit --testsuite Conformance
// Tier 4/5 — Visual + Golden: rendered/serialized output vs a pinned// reference (golden is byte/structure-pinned, never auto-updated).// vendor/bin/phpunit --testsuite Golden
// A change to the document facade touches every API, so the routing// guidance escalates it from "unit only" to the full unit + integration// surface — the tier you run is a function of blast radius, not habit.這個範例的重點在於路由邏輯,而非那些指令本身。你要操作哪一層,是由這項變更可能破壞什麼來決定。這套基礎設施讓每一層都成為一等的、可分別執行的目標。
常見的誤解
標題為「常見的誤解」的區段金字塔常被解讀成一種排名——單元測試在底部是因為它們最不重要、端到端在頂端是因為它們最重要(或反過來)。兩者皆非。縱軸大致是成本與數量:大量快速、廉價的單元測試構成寬闊的底部;往上則是逐漸減少、較慢、保真度更高的測試。黃金測試並不比單元測試「更好」。它捕捉的是不同的失敗,發生得更晚、代價更高,而且拿它來取代其下數以千計的快速檢查會是個糟糕的選擇。
第二個誤解是,認為高覆蓋率數字代表金字塔是健全的。並非如此。覆蓋率衡量的是執行,而非偵測。這些標準明確拒絕將覆蓋率排序等同於找出缺陷的能力。這道落差正是變異測試存在所要揭露的。
限制與邊界
標題為「限制與邊界」的區段本頁描述的是這項策略的形狀與意圖,而非它目前的結果。測試數量、覆蓋率百分比與變異分數在此刻意從缺。它們是動態的品質訊號,會由持續整合產出物生成。目前的數字會隨建置一起發布。若將它們凍結成文字敘述,它們會悄悄地過時。唯一陳述的數字——PHPStan Level 10——是一項穩定的設定事實,可在引擎的靜態分析設定中查證,並非一項量測值。
層級的名稱是穩定的架構術語。套件的確切組成及其執行設定會隨引擎演進,並由測試設定所掌管;若測試設定與本說明有任何出入,以測試設定為準。本頁並未主張任何特定的通過率,也未與任何其他程式庫的測試策略進行比較。
相關文件
標題為「相關文件」的區段- 黃金檔測試——頂端層級如何釘定參照輸出並維持可信度。
- 變異測試詳解——為什麼覆蓋率數字無法證明這些層級中的測試真的有效。
- 處處嚴格型別——PHPStan Level 10 如何在任何層級執行之前就消除一整類缺陷。
詞彙表
標題為「詞彙表」的區段- 測試層級(Test tier)——策略中負責證明某一種性質的層級(例如,單元行為或結構有效性)。NextPDF 使用五個。
- 結構測試(Structural test)——檢查所產生 PDF 的物件圖、交叉參照表與尾段是否格式正確且符合規範,而非僅檢查回傳值。
- 視覺測試(Visual test)——檢查算繪後的頁面是否在所宣告的容差範圍內與一張核准的參照影像相符。
- 黃金測試(Golden test)——針對一份從不自動更新的釘定參照輸出所做的端到端檢查;它是「輸出未曾改變」的契約。
- 測試有效性(Test effectiveness)——一組測試揭露缺陷的能力,ISO/IEC/IEEE 29119-4 將其與覆蓋率區分開來。縮寫附註:MSI(Mutation Score Indicator,變異分數指標)的定義見變異測試頁面。
- PHPStan Level 10——最嚴格的靜態分析等級;NextPDF 以鎖定為零的錯誤預算執行它。