Bỏ qua để đến nội dung

Kiểm thử golden file

Spec: ISO/IEC/IEEE 29119-4 Spec: ISO/IEC 25010 Evidence: Test-backed

Golden file là một bản ghi “đầu ra đúng trông như thế này” mà một bài kiểm thử đối chiếu trong mỗi lần chạy. NextPDF dùng các golden để phát hiện thay đổi ngoài ý muốn: một luồng nén thay đổi, một đoạn văn bị xê dịch, hoặc một tọa độ bị lệch. Trang này giải thích cách cơ chế đó hoạt động và cách một golden giữ được độ tin cậy thay vì trở thành một tham chiếu lỗi thời mà không ai đọc.

Việc tạo PDF là một pipeline dài với nhiều điểm có thể âm thầm sai lệch. Một lần refactor “không thay đổi gì” có thể lặng lẽ sắp xếp lại các toán tử, thay đổi một ma trận biến đổi, hoặc dịch một ô bảng đi một lượng rất nhỏ. Unit test hiếm khi phát hiện điều này: chúng kiểm chứng một giá trị mà bạn nghĩ đến để kiểm tra, chứ không phải hàng nghìn byte mà bạn không lường đến. Các kỹ thuật dựa trên cấu trúc và dựa trên đặc tả phát hiện những lỗi khác nhau, và không kỹ thuật nào thay thế hoàn toàn kỹ thuật kia (ISO/IEC/IEEE 29119-4, Annex A). Golden file là đặc tả-bằng-ví-dụ ghim toàn bộ đầu ra, chứ không phải một phép kiểm chứng đơn lẻ.

Rủi ro tồn tại theo cả hai hướng. Một golden quá khắt khe sẽ thất bại trước mọi thay đổi vô hại và bị duyệt lại một cách mù quáng cho đến khi nó chẳng chứng minh được điều gì. Một golden quá lỏng lẻo sẽ để cho các hồi quy thực sự lọt qua. Đạt được sự cân bằng đó chính là phần khó nhất của kỷ luật này.

  • Một golden file là một đầu ra tham chiếu đã ghim, được tạo ra từ hành vi đã biết là đúng của công cụ và được commit vào repository.
  • Một bài kiểm thử golden tạo lại đầu ra và so sánh khác biệt với tham chiếu đã ghim; bất kỳ khác biệt nào cũng làm bài kiểm thử thất bại và cần con người quyết định.
  • NextPDF so sánh ở cấp độ có ý nghĩa nhưng ổn định: văn bản được trích xuất và các toán tử cấu trúc đã chuẩn hóa, chứ không phải byte thô, vì byte thô mang theo nhiễu (dấu thời gian, thứ tự subset, nén) vốn không phải là hồi quy.
  • Cập nhật một golden là một hành động có chủ đích, đã được duyệt, ẩn sau một công tắc GOLDEN_UPDATE tường minh — không bao giờ là thao tác tự động “chấp nhận bất cứ thứ gì đã thay đổi”.
  • Golden khác với kiểm thử snapshot và kiểm thử characterization ở một điểm then chốt: một golden không bao giờ được tự động cập nhật.

Hạ tầng golden của công cụ dùng một phép so sánh khác biệt hai lớp rõ ràng thay vì so sánh byte:

  1. Generate Render the fixture input through the current engine.
  2. Layer 1 — text Extract human-readable text from the content stream; diff against the text golden. Catches dropped or reordered content and encoding regressions.
  3. Layer 2 — structure Extract ordered PDF operators, normalise coordinates to a fixed precision, diff against the operator golden. Catches layout shifts and broken structure.
  4. Decide Any diff fails the test; a human judges whether it is a regression or an intended change.
Cách một phép so sánh golden của NextPDF chạy: tạo PDF, trích xuất các lớp có ý nghĩa (văn bản, rồi đến các toán tử cấu trúc đã chuẩn hóa), so sánh khác biệt từng lớp với tham chiếu đã ghim, và thất bại kèm một báo cáo dễ đọc cho con người khi có bất kỳ khác biệt nào.

Những gì hệ thống cố ý không so sánh cũng quan trọng như những gì nó so sánh. Đầu ra byte thô bị loại trừ vì dấu thời gian, thứ tự font subset và việc nén luồng khiến nó dễ vỡ mà không làm nó đúng hơn. So sánh khác biệt hình ảnh ở cấp pixel bị loại khỏi tầng này vì nó cần một bộ kết xuất bên ngoài và mang theo biến thiên của môi trường. Các tọa độ dấu phẩy động được chuẩn hóa về một độ chính xác cố định để nhiễu làm tròn vô nghĩa không bị nhận nhầm là hồi quy. Đây là sự khác biệt giữa một golden kiểm thử hành vi và một golden kiểm thử nhiễu môi trường nhất thời.

Lựa chọn này cũng xác định hồ sơ khả năng tái lập của trang: structural. NextPDF ghi nhận ba hồ sơ — bitwise (tái lập đúng từng byte), structural (tái lập đồ thị đối tượng và chuỗi toán tử, cho phép biến thiên lành tính ở cấp byte), và semantic (tái lập ý nghĩa). Các bài kiểm thử golden ở tầng này, theo thiết kế, kiểm chứng hồ sơ structural. Đó là lý do các tham chiếu của chúng vẫn ổn sau một lần nâng cấp thư viện nén nhưng vẫn thất bại trước một bảng bị xê dịch.

Evidence: Test-backed Phép so sánh hai lớp (trích xuất văn bản, rồi so sánh toán tử cấu trúc đã chuẩn hóa) là phương pháp golden đã được chính công cụ tài liệu hóa; trong đó so sánh byte thô, khác biệt hình ảnh và dấu phẩy động chính xác được loại khỏi phạm vi một cách tường minh vì những lý do nêu trên. Bộ golden là một bộ kiểm thử được khai báo, có thể chạy riêng, tách biệt với bộ snapshot và bộ characterization.

Evidence: Test-backed Cơ chế giữ cho golden trung thực là cụ thể: các tham chiếu golden là sản phẩm được tạo ra, không phải viết tay. Việc ghi đè chúng được kiểm soát bằng một công tắc môi trường GOLDEN_UPDATE tường minh, được ghi nhận là một thao tác hiếm, luôn được duyệt. Ngược lại, các bài kiểm thử snapshot trong công cụ tạo lại ở lần chạy đầu và thừa nhận sai lệch thông qua một cờ cập nhật. Và các bài kiểm thử characterization khóa lại hành vi cũ mà không khẳng định rằng nó đúng. Ba thứ này được chủ đích thiết kế để đóng vai trò khác nhau.

Evidence: Standard-backed Một golden là một đặc tả-bằng-ví-dụ. Spec: ISO/IEC/IEEE 29119-4, Annex A ghi nhận rằng các kỹ thuật dựa trên đặc tả và dựa trên cấu trúc phát hiện những lớp lỗi khác nhau, và một chiến lược nên kết hợp chúng. Đó là lý do các golden đứng cạnh, chứ không thay thế, các bài unit test và kiểm thử cấu trúc trong kim tự tháp kiểm thử.

Về mặt cơ chế, một bài kiểm thử golden rất đơn giản; kỷ luật nằm ở quy trình làm việc xung quanh nó:

<?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.

Điểm chính của ví dụ là quy trình. Mã kiểm thử chỉ thực hiện so sánh khác biệt. Điều khiến golden đáng tin cậy là một tham chiếu bị thay đổi được duyệt như một đầu ra trong cùng một thay đổi đã làm thay đổi công cụ.

Sai lầm phổ biến nhất là xem kiểm thử golden như kiểm thử từng byte. Các golden của NextPDF không phải là các byte của tệp — chúng là văn bản được trích xuất và các toán tử cấu trúc đã chuẩn hóa của tệp. Kiểm chứng byte thô sẽ thất bại với một phiên bản zlib mới, một thẻ subset khác, hoặc một dấu thời gian được tạo lại, dù không yếu tố nào trong số đó là hồi quy. Bài kiểm thử sẽ bị duyệt lại để cho qua đến mức vô dụng chỉ trong vòng một tuần. (Ở những nơi đúng từng byte thực sự phải được tái lập, đó là hồ sơ khả năng tái lập bitwise riêng biệt, khắt khe hơn, không phải một golden.)

Sai lầm thứ hai là cho rằng một bộ golden toàn xanh chứng minh tính đúng đắn. Nó chứng minh sự không thay đổi. Một golden được tạo ra từ đầu ra có lỗi sẽ bảo vệ lỗi đó một cách trung thành. Các golden bảo vệ trước hồi quy so với một mốc nền đã biết là đúng; chúng không xác lập rằng mốc nền đó là đúng. Đó là vai trò của các tầng unit, cấu trúc và tuân thủ.

Một bài kiểm thử golden chỉ trả lời một câu hỏi: đầu ra có thay đổi so với tham chiếu đã ghim hay không. Nó không cho biết tham chiếu đó đã từng đúng hay chưa. Nó cũng không đo lường hiệu năng, sự tuân thủ hay bảo mật. Đó là những tầng khác. Kích thước kho fixture, tỷ lệ vượt qua của bộ kiểm thử và bất kỳ con số độ phủ nào đều là các tín hiệu chất lượng động, được tạo ra từ các artifact tích hợp liên tục và công bố cùng bản build. Chúng cố ý không được nêu ở đây, vì ở đây chúng có thể trở nên lỗi thời.

Bố cục thư mục chính xác, nội bộ của bộ so sánh và công tắc cập nhật thuộc về hạ tầng kiểm thử của công cụ và có thể thay đổi. Cấu hình kiểm thử là nguồn có thẩm quyền nếu từng có mâu thuẫn với phần giải thích này. Trang này không đưa ra tuyên bố nào về công cụ snapshot hay golden của bất kỳ thư viện nào khác.

  • Golden file — một đầu ra tham chiếu đã ghim, được tạo ra từ hành vi đã biết là đúng của công cụ và đã được commit, mà một bài kiểm thử so sánh khác biệt trong mỗi lần chạy. Không bao giờ được tự động cập nhật.
  • So sánh khác biệt hai lớp — phép so sánh golden của NextPDF: văn bản được trích xuất (Lớp 1) cùng các toán tử cấu trúc đã chuẩn hóa (Lớp 2), thay cho byte thô.
  • Kiểm thử snapshot — một kỹ thuật liên quan nhưng khác biệt, trong đó tham chiếu được tạo lại ở lần chạy đầu và sai lệch được thừa nhận thông qua một cờ cập nhật.
  • Kiểm thử characterization — một bài kiểm thử khóa lại hành vi hiện có mà không khẳng định rằng nó đúng, thường là để làm cho một lần refactor an toàn.
  • Hồ sơ khả năng tái lập — cấp độ mà đầu ra phải tái lập: bitwise (đúng từng byte), structural (đồ thị đối tượng và chuỗi toán tử, cho phép biến thiên lành tính ở cấp byte), hoặc semantic (ý nghĩa). Các bài kiểm thử golden ở đây kiểm chứng hồ sơ structural.
  • GOLDEN_UPDATE — công tắc môi trường tường minh cho phép ghi đè các tham chiếu golden; một thao tác hiếm, đã được duyệt.