การทดสอบด้วย Golden file
Spec: ISO/IEC/IEEE 29119-4 ISO/IEC/IEEE 29119-4 Spec: ISO/IEC 25010 ISO/IEC 25010 Evidence: Test-backed
ภาพรวมโดยสังเขป
หัวข้อที่มีชื่อว่า “ภาพรวมโดยสังเขป”Golden file คือบันทึกที่ระบุว่า “เอาต์พุตที่ถูกต้องมีลักษณะอย่างไร” ซึ่งการทดสอบใช้เปรียบเทียบทุกครั้งที่รัน NextPDF ใช้ golden เพื่อตรวจจับการเปลี่ยนแปลงที่ไม่ได้ตั้งใจ เช่น สตรีมที่ถูกบีบอัดต่างไป ย่อหน้าที่ขยับตำแหน่ง หรือพิกัดที่คลาดเคลื่อนไป หน้านี้อธิบายว่ากระบวนการดังกล่าวทำงานอย่างไร และทำให้ golden ยังคงน่าเชื่อถือได้อย่างไรแทนที่จะกลายเป็นการอ้างอิงที่ล้าสมัยซึ่งไม่มีใครอ่าน
เหตุใดเรื่องนี้จึงสำคัญ
หัวข้อที่มีชื่อว่า “เหตุใดเรื่องนี้จึงสำคัญ”การสร้าง PDF เป็นไปป์ไลน์ที่ยาว ซึ่งมีจุดมากมายที่อาจคลาดเคลื่อนไปอย่างเงียบๆ การรีแฟกเตอร์ที่ “ไม่ได้เปลี่ยนแปลงอะไร” อาจจัดลำดับโอเปอเรเตอร์ใหม่ เปลี่ยน transform matrix หรือขยับเซลล์ในตารางไปเล็กน้อยอย่างเงียบๆ Unit test มักจับสิ่งนี้ไม่ได้ เพราะตรวจยืนยันเฉพาะค่าที่ผู้เขียนนึกถึงว่าจะตรวจ ไม่ใช่ไบต์อีกหลายพันไบต์ที่ไม่ได้ตรวจ เทคนิคที่อิงโครงสร้างและที่อิงข้อกำหนดตรวจพบข้อผิดพลาดคนละแบบ และไม่มีเทคนิคใดครอบคลุมอีกเทคนิคหนึ่งได้ (ISO/IEC/IEEE 29119-4, Annex A) Golden file คือข้อกำหนดในรูปแบบตัวอย่างที่ตรึงเอาต์พุต ทั้งหมด ไว้ ไม่ใช่การตรวจยืนยันเพียงข้อเดียว
ความเสี่ยงเกิดขึ้นได้ทั้งสองทาง Golden ที่เข้มงวดเกินไปจะล้มเหลวกับทุกการเปลี่ยนแปลงที่ไม่เป็นอันตราย และถูกอนุมัติใหม่แบบไม่ใส่ใจจนพิสูจน์อะไรไม่ได้เลย Golden ที่หละหลวมเกินไปจะปล่อยให้การถดถอยที่แท้จริงผ่านไปได้ การหาจุดสมดุลให้พอดีคือหัวใจของแนวทางนี้
ฉบับย่อ
หัวข้อที่มีชื่อว่า “ฉบับย่อ”- Golden file คือเอาต์พุตอ้างอิงที่ตรึงไว้ ซึ่งสร้างขึ้นจากพฤติกรรมของเอนจินที่ทราบแล้วว่าถูกต้อง และคอมมิตเข้าสู่ repository
- Golden test จะสร้างเอาต์พุตขึ้นใหม่และ เปรียบเทียบความแตกต่างกับการอ้างอิงที่ตรึงไว้ ความแตกต่างใดๆ จะทำให้การทดสอบล้มเหลวและต้องอาศัยการตัดสินใจจากมนุษย์
- NextPDF เปรียบเทียบที่ระดับซึ่ง มีความหมายและเสถียร ได้แก่ ข้อความที่สกัดออกมาและโอเปอเรเตอร์เชิงโครงสร้างที่ทำให้เป็นมาตรฐานแล้ว ไม่ใช่ไบต์ดิบ เพราะไบต์ดิบมีสัญญาณรบกวน (ไทม์สแตมป์ ลำดับของซับเซ็ต การบีบอัด) ซึ่งไม่ใช่การถดถอย
- การอัปเดต golden เป็นการดำเนินการโดยเจตนาและผ่านการตรวจทาน โดยอยู่หลังสวิตช์
GOLDEN_UPDATEที่ระบุไว้อย่างชัดเจน ไม่ใช่การ “ยอมรับสิ่งใดก็ตามที่เปลี่ยนไป” โดยอัตโนมัติ - Golden แตกต่างจากการทดสอบแบบ snapshot และ characterization ในจุดสำคัญหนึ่งจุด คือ golden จะ ไม่อัปเดตโดยอัตโนมัติ โดยเด็ดขาด
แนวทางของ NextPDF
หัวข้อที่มีชื่อว่า “แนวทางของ NextPDF”โครงสร้างพื้นฐานสำหรับ golden ในเอนจินใช้ การเปรียบเทียบความแตกต่างสองชั้น ที่ระบุไว้อย่างชัดเจน แทนการเปรียบเทียบแบบไบต์ต่อไบต์
- 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.
สิ่งที่จงใจ ไม่ นำมาเปรียบเทียบมีความสำคัญเท่ากับสิ่งที่นำมาเปรียบเทียบ เอาต์พุตแบบไบต์ดิบถูกตัดออกไป เพราะไทม์สแตมป์ ลำดับของฟอนต์ซับเซ็ต และการบีบอัดสตรีมเพิ่มความเปราะบางโดยไม่ได้เพิ่มความถูกต้อง การเปรียบเทียบภาพในระดับพิกเซลถูกตัดออกจากชั้นนี้ เพราะต้องใช้ตัวเรนเดอร์ภายนอกและนำความผันแปรของสภาพแวดล้อมเข้ามา พิกัดแบบ floating-point จะถูกทำให้เป็นมาตรฐานที่ความแม่นยำคงที่ เพื่อไม่ให้สัญญาณรบกวนจากการปัดเศษที่ไร้ความหมายถูกเข้าใจผิดว่าเป็นการถดถอย นี่คือความแตกต่างระหว่าง golden ที่ทดสอบ พฤติกรรม กับ golden ที่ทดสอบ สัญญาณรบกวนชั่วคราวของสภาพแวดล้อม นั่นเอง
การเลือกเช่นนี้ยังระบุโปรไฟล์ความสามารถในการทำซ้ำของหน้านี้ด้วย คือ structural NextPDF จัดทำเอกสารโปรไฟล์ไว้สามแบบ ได้แก่ bitwise (ไบต์ที่เหมือนกันทุกประการทำซ้ำได้) structural (กราฟของออบเจกต์และลำดับโอเปอเรเตอร์ทำซ้ำได้ โดยอนุญาตให้มีความผันแปรในระดับไบต์ที่ไม่เป็นอันตราย) และ semantic (ความหมายทำซ้ำได้) Golden test ในชั้นนี้ตรวจยืนยันโปรไฟล์ structural โดยการออกแบบ นั่นคือเหตุผลที่การอ้างอิงเหล่านี้ยังอยู่รอดเมื่อมีการอัปเกรดไลบรารีบีบอัด แต่ยังคงล้มเหลวเมื่อตารางถูกขยับ
หลักฐานบอกอะไร
หัวข้อที่มีชื่อว่า “หลักฐานบอกอะไร”Evidence: Test-backed การเปรียบเทียบสองชั้น (การสกัด ข้อความ จากนั้นการเปรียบเทียบโอเปอเรเตอร์เชิงโครงสร้างที่ทำให้เป็นมาตรฐานแล้ว) คือ วิธีการ golden ที่เอนจินจัดทำเอกสารไว้เอง โดยการเปรียบเทียบแบบไบต์ดิบ การเปรียบเทียบภาพ และการเปรียบเทียบค่า float แบบเป๊ะๆ อยู่นอกขอบเขตอย่างชัดเจนด้วยเหตุผลข้างต้น ชุดทดสอบ golden เป็น ชุดทดสอบที่ประกาศไว้และรันแยกได้ ซึ่งแตกต่างจากชุดทดสอบ snapshot และ characterization
Evidence: Test-backed กลไกรักษาความน่าเชื่อถือนั้นเป็นรูปธรรม
การอ้างอิง golden เป็นสิ่งที่สร้างขึ้น ไม่ใช่เขียนด้วยมือ การเขียนทับ
การอ้างอิงเหล่านั้นถูกควบคุมด้วยสวิตช์สภาพแวดล้อม GOLDEN_UPDATE ที่ระบุไว้อย่างชัดเจน ซึ่งจัดทำเอกสารไว้
ในฐานะการดำเนินการที่เกิดขึ้นไม่บ่อยและผ่านการตรวจทานเสมอ ในทางตรงกันข้าม การทดสอบ snapshot ใน
เอนจินจะสร้างขึ้นใหม่ในการรันครั้งแรกและรับรู้การเปลี่ยนแปลงผ่านแฟล็กอัปเดต และ
การทดสอบ characterization จะตรึงพฤติกรรมเดิมไว้โดยไม่ได้อ้างว่าพฤติกรรมนั้น
ถูกต้อง ทั้งสามอย่างเป็นเครื่องมือที่ถูกออกแบบให้แตกต่างกันโดยเจตนา
Evidence: Standard-backed Golden คือ ข้อกำหนดในรูปแบบตัวอย่าง Spec: ISO/IEC/IEEE 29119-4, Annex A ISO/IEC/IEEE 29119-4 Annex A ระบุว่าเทคนิคที่อิงข้อกำหนดและที่อิงโครงสร้างจับข้อผิดพลาด คนละกลุ่ม และกลยุทธ์ควรนำทั้งสองมารวมกัน นั่นคือเหตุผลที่ golden อยู่เคียงข้างการทดสอบ unit และ structural ใน testing pyramid นั่นเอง
ตัวอย่างเชิงปฏิบัติ
หัวข้อที่มีชื่อว่า “ตัวอย่างเชิงปฏิบัติ”ในเชิงกลไก Golden test นั้นเรียบง่าย วินัยที่สำคัญอยู่ในเวิร์กโฟลว์รอบๆการทดสอบนั้น
<?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.ตัวอย่างนี้แสดงกระบวนการ โค้ดของการทดสอบทำเพียงเปรียบเทียบความแตกต่างเท่านั้น สิ่งที่ทำให้ golden น่าเชื่อถือคือการอ้างอิงที่เปลี่ยนไปจะถูกตรวจทาน ในฐานะเอาต์พุต ภายในการเปลี่ยนแปลงเดียวกับที่แก้ไขเอนจิน
ความเข้าใจผิดที่พบบ่อย
หัวข้อที่มีชื่อว่า “ความเข้าใจผิดที่พบบ่อย”ความผิดพลาดที่พบบ่อยที่สุดคือการมองการทดสอบ golden ว่าเป็นการทดสอบแบบไบต์ต่อไบต์ Golden ของ NextPDF ไม่ใช่ไบต์ดิบของไฟล์ แต่เป็นข้อความที่สกัดออกมาและโอเปอเรเตอร์เชิงโครงสร้างที่ทำให้เป็นมาตรฐานแล้วของไฟล์นั้น การตรวจยืนยันไบต์ดิบจะล้มเหลวเมื่อมี zlib เวอร์ชันใหม่ แท็กซับเซ็ตที่ต่างไป หรือไทม์สแตมป์ที่สร้างขึ้นใหม่ ซึ่งล้วนไม่ใช่การถดถอย การทดสอบจะถูกอนุมัติใหม่จนหมดประโยชน์ภายในหนึ่งสัปดาห์ (ในกรณีที่ไบต์ที่เหมือนกันทุกประการต้องทำซ้ำได้จริงๆ นั่นคือโปรไฟล์ความสามารถในการทำซ้ำ bitwise ที่แยกต่างหากและเข้มงวดกว่า ไม่ใช่ golden)
ความผิดพลาดข้อที่สองคือการสันนิษฐานว่าชุดทดสอบ golden ที่ผ่าน (สีเขียว) พิสูจน์ความถูกต้อง สิ่งที่พิสูจน์ได้คือ การไม่เปลี่ยนแปลง Golden ที่สร้างขึ้นจากเอาต์พุตที่มีบั๊กจะตรึงบั๊กนั้นไว้อย่างซื่อสัตย์ Golden ป้องกันการถดถอยจากเส้นฐานที่ทราบแล้วว่าถูกต้อง แต่ไม่ได้ยืนยันว่าเส้นฐานนั้นถูกต้องจริง นั่นคือหน้าที่ของชั้น unit, structural และ conformance
ข้อจำกัดและขอบเขต
หัวข้อที่มีชื่อว่า “ข้อจำกัดและขอบเขต”Golden test ตอบคำถามเพียงข้อเดียวเท่านั้น คือเอาต์พุตเปลี่ยนไปจากการอ้างอิงที่ตรึงไว้หรือไม่ การทดสอบไม่ได้บอกว่าการอ้างอิงนั้นเคยถูกต้องหรือไม่ ทั้งยังไม่ได้วัดประสิทธิภาพ ความสอดคล้องตามมาตรฐาน หรือความปลอดภัย สิ่งเหล่านั้นเป็นหน้าที่ของชั้นอื่น ขนาดของคลังฟิกซ์เจอร์ อัตราการผ่านของชุดทดสอบ และตัวเลขความครอบคลุมใดๆ เป็นสัญญาณคุณภาพที่มีการเปลี่ยนแปลงตลอดเวลา ซึ่งสร้างขึ้นจากอาร์ติแฟกต์ของ continuous integration และเผยแพร่พร้อมกับบิลด์ ค่าเหล่านี้จึงจงใจไม่ระบุไว้ที่นี่ เพราะอาจล้าสมัยได้
เค้าโครงไดเรกทอรีที่แน่นอน รายละเอียดภายในของตัวเปรียบเทียบ และสวิตช์อัปเดต เป็นของโครงสร้างพื้นฐานการทดสอบของเอนจินและอาจเปลี่ยนแปลงได้ การกำหนดค่าการทดสอบถือเป็นแหล่งอ้างอิงที่มีอำนาจหากขัดแย้งกับคำอธิบายนี้ หน้านี้ไม่ได้กล่าวอ้างใดๆ เกี่ยวกับเครื่องมือ snapshot หรือ golden ของไลบรารีอื่น
เอกสารที่เกี่ยวข้อง
หัวข้อที่มีชื่อว่า “เอกสารที่เกี่ยวข้อง”- พีระมิดการทดสอบของ NextPDF — ตำแหน่งของชั้น golden ในทั้งห้าชั้น และสิ่งที่ชั้นนี้พิสูจน์ได้อย่างเป็นเอกลักษณ์
- Mutation testing, explained — วิธีที่ NextPDF ตรวจสอบว่าการทดสอบของตน รวมถึง golden ตรวจพบข้อบกพร่องได้จริง
- Strict types, everywhere — การวิเคราะห์แบบสถิตที่ขจัดข้อบกพร่องกลุ่มหนึ่งออกไปก่อนที่ golden ใดๆ จะรัน
อภิธานศัพท์
หัวข้อที่มีชื่อว่า “อภิธานศัพท์”- Golden file — เอาต์พุตอ้างอิงที่ตรึงไว้ ซึ่งสร้างขึ้นจากพฤติกรรมของเอนจินที่ทราบแล้วว่าถูกต้องและคอมมิตไว้ โดยการทดสอบจะนำมาเปรียบเทียบความแตกต่างทุกครั้งที่รัน ไม่อัปเดตโดยอัตโนมัติเด็ดขาด
- Two-layer diff — การเปรียบเทียบ golden ของ NextPDF ได้แก่ ข้อความที่สกัดออกมา (Layer 1) ร่วมกับโอเปอเรเตอร์เชิงโครงสร้างที่ทำให้เป็นมาตรฐานแล้ว (Layer 2) แทนการใช้ไบต์ดิบ
- Snapshot test — เทคนิคที่เกี่ยวข้องแต่แตกต่าง ซึ่งการอ้างอิงจะถูกสร้างขึ้นใหม่ในการรันครั้งแรกและรับรู้การเปลี่ยนแปลงผ่านแฟล็กอัปเดต
- Characterization test — การทดสอบที่ตรึงพฤติกรรมที่มีอยู่เดิมไว้โดยไม่ได้ตรวจยืนยันว่าถูกต้อง โดยทั่วไปทำเพื่อให้การรีแฟกเตอร์ปลอดภัย
- Reproducibility profile — ระดับที่เอาต์พุตต้องทำซ้ำได้ ได้แก่ bitwise (ไบต์ที่เหมือนกันทุกประการ) structural (กราฟของออบเจกต์และลำดับโอเปอเรเตอร์ โดยอนุญาตให้มีความผันแปรในระดับไบต์ที่ไม่เป็นอันตราย) หรือ semantic (ความหมาย) Golden test ในที่นี้ตรวจยืนยันโปรไฟล์ structural
GOLDEN_UPDATE— สวิตช์สภาพแวดล้อมที่ระบุไว้อย่างชัดเจน ซึ่งอนุญาตให้เขียนทับการอ้างอิง golden ได้ โดยเป็นการดำเนินการที่เกิดขึ้นไม่บ่อยและผ่านการตรวจทาน