골든 파일 테스트
Spec: ISO/IEC/IEEE 29119-4 ISO/IEC/IEEE 29119-4 Spec: ISO/IEC 25010 ISO/IEC 25010 Evidence: Test-backed
한눈에 보기
섹션 제목: “한눈에 보기”골든 파일이란 “올바른 출력은 이런 모습이다”라고 기록해 둔 것으로, 테스트는 실행할 때마다 이것과 대조합니다. NextPDF는 골든을 사용해 아무도 의도하지 않은 변경을 잡아냅니다. 압축 방식이 달라진 스트림, 위치가 옮겨진 단락, 어긋난 좌표 같은 것들입니다. 이 페이지에서는 그것이 어떻게 작동하는지, 그리고 골든이 아무도 읽지 않는 낡은 참조가 되는 대신 어떻게 신뢰할 수 있는 상태로 유지되는지를 설명합니다.
왜 중요한가
섹션 제목: “왜 중요한가”PDF 생성은 긴 파이프라인이며, 조용히 드리프트할 수 있는 지점이 수없이 많습니다. “아무것도 바꾸지 않은” 리팩터링이 자기도 모르게 연산자의 순서를 뒤바꾸거나, 변환 행렬을 바꾸거나, 테이블 셀을 아주 미세하게 옮길 수 있습니다. 유닛 테스트는 이런 변화를 좀처럼 잡아내지 못합니다. 확인하려고 마음먹은 값은 검증하지만, 미처 생각하지 못한 수천 바이트는 검증하지 않기 때문입니다. 구조 기반 기법과 사양 기반 기법은 서로 다른 종류의 오류를 검출하며, 어느 한쪽이 다른 쪽을 포함하지 않습니다(ISO/IEC/IEEE 29119-4, Annex A). 골든 파일은 하나의 단언이 아니라 전체 출력을 고정하는, 예시에 의한 사양입니다.
위험은 양방향으로 작용합니다. 너무 엄격한 골든은 무해한 변경마다 실패하다가, 아무것도 증명하지 못할 때까지 맹목적으로 다시 승인됩니다. 너무 느슨한 골든은 진짜 리그레션을 통과시킵니다. 그 균형을 제대로 잡는 것이야말로 이 기법의 핵심입니다.
- 골든 파일은 정상으로 알려진 엔진 동작에서 생성되어 리포지토리에 커밋된, 고정된 참조 출력입니다.
- 골든 테스트는 출력을 다시 생성하고 고정된 참조와 차이를 비교합니다. 어떤 차이라도 발생하면 테스트는 실패하고, 사람의 판단을 요구합니다.
- NextPDF는 의미가 있으면서도 안정적인 수준에서 비교합니다. 즉, 원시 바이트가 아니라 추출된 텍스트와 정규화된 구조 연산자를 비교합니다. 원시 바이트는 리그레션이 아닌 노이즈(타임스탬프, 서브셋 순서, 압축)를 담고 있기 때문입니다.
- 골든을 갱신하는 일은 명시적인
GOLDEN_UPDATE스위치를 통해서만 이루어지는, 의도적이고 검토를 거친 행위입니다. 무엇이 바뀌든 자동으로 “받아들이는” 일은 결코 없습니다. - 골든은 스냅샷 테스트나 특성화 테스트와 결정적인 한 가지 점에서 다릅니다. 골든은 결코 자동으로 갱신되지 않는다는 점입니다.
NextPDF가 접근하는 방식
섹션 제목: “NextPDF가 접근하는 방식”엔진의 골든 인프라는 바이트 비교가 아니라 명시적인 2계층 차이 비교를 사용합니다.
- 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.
비교하지 않는 것은 비교하는 것만큼이나 중요합니다. 원시 바이트 출력은 제외됩니다. 타임스탬프, 폰트 서브셋 순서, 스트림 압축이 정확성을 높이지도 못하면서 테스트를 취약하게 만들기 때문입니다. 픽셀 단위 이미지 차이 비교는 외부 렌더러를 필요로 하고 환경 편차를 끌어들이므로 이 계층에서 제외됩니다. 부동소수점 좌표는 고정 정밀도로 정규화되므로, 의미 없는 반올림 노이즈가 리그레션인 척하지 못합니다. 이것이 동작을 테스트하는 골든과 일시적인 환경 노이즈를 테스트하는 골든의 차이입니다.
이 선택은 이 페이지의 재현성 프로파일도 명명합니다. 바로 **structural(구조적)**입니다. NextPDF는 세 가지 프로파일을 문서화합니다. bitwise(정확한 바이트가 재현됨), structural(객체 그래프와 연산자 시퀀스가 재현되며, 무해한 바이트 수준의 편차는 허용됨), semantic(의미가 재현됨)입니다. 이 계층의 골든 테스트는 설계상 구조적 프로파일을 단언합니다. 그래서 이들의 참조는 압축 라이브러리 버전 업에는 견디면서도 옮겨진 테이블에는 여전히 실패합니다.
증거가 말하는 것
섹션 제목: “증거가 말하는 것”Evidence: Test-backed 2계층 비교(텍스트 추출 후 정규화된 구조 연산자 비교)는 엔진 자신이 문서화한 골든 방법론이며, 원시 바이트, 이미지 차이, 정확한 부동소수점 비교는 위에서 설명한 이유로 명시적으로 범위에서 제외됩니다. 골든 스위트는 명시적으로 선언되어 개별적으로 실행할 수 있는 테스트 스위트로, 스냅샷 스위트 및 특성화 스위트와 구별됩니다.
Evidence: Test-backed 정직성을 보장하는 메커니즘은 구체적입니다.
골든 참조는 손으로 작성한 것이 아니라 생성된 산출물입니다. 이를 덮어쓰는 일은
명시적인 GOLDEN_UPDATE 환경 스위치 뒤에서 게이트되며,
드물고 항상 검토를 거치는 작업으로 문서화되어 있습니다. 이와 대조적으로 엔진의
스냅샷 테스트는 첫 실행 시 다시 생성되며 갱신 플래그를 통해 드리프트를 받아들입니다. 그리고
특성화 테스트는 레거시 동작이 올바르다고 주장하지 않으면서 그것을
고정합니다. 이 셋은 의도적으로 서로 다른 도구입니다.
Evidence: Standard-backed 골든은 예시에 의한 사양입니다. Spec: ISO/IEC/IEEE 29119-4, Annex A ISO/IEC/IEEE 29119-4 Annex A 는 사양 기반 기법과 구조 기반 기법이 서로 다른 종류의 오류를 잡아내며, 전략은 이들을 결합해야 한다고 명시합니다. 그래서 골든은 테스팅 피라미드 안에서 유닛 테스트 및 구조 테스트를 대체하는 것이 아니라 그것들과 나란히 자리합니다.
실용적인 예제
섹션 제목: “실용적인 예제”골든 테스트는 메커니즘으로는 단순합니다. 규율이 요구되는 부분은 그 주위를 둘러싼 워크플로입니다.
<?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.이 예제가 보여 주는 것은 프로세스 자체입니다. 테스트 코드는 차이를 비교할 뿐입니다. 골든을 신뢰할 수 있게 만드는 것은, 변경된 참조가 엔진을 바꾼 바로 그 변경 안에서 출력으로서 검토된다는 점입니다.
흔한 오해
섹션 제목: “흔한 오해”가장 흔한 실수는 골든 테스트를 바이트 단위 테스트로 다루는 것입니다. NextPDF의 골든은 파일의 바이트가 아니라, 추출된 텍스트와 정규화된 구조 연산자입니다. 원시 바이트를 단언하면 새로운 zlib 버전, 다른 서브셋 태그, 또는 다시 생성된 타임스탬프에서 실패하지만, 그 어느 것도 리그레션이 아닙니다. 그런 테스트는 일주일도 안 되어 거듭 다시 승인되며 쓸모없는 상태가 되어 버립니다. (정확한 바이트가 정말로 재현되어야 하는 경우, 그것은 골든이 아니라 별개의 더 엄격한 bitwise 재현성 프로파일입니다.)
두 번째 실수는 골든 스위트가 초록색이면 정확성이 증명된다고 가정하는 것입니다. 그것이 증명하는 것은 변하지 않았다는 것입니다. 버그가 있는 출력에서 생성된 골든은 그 버그를 충실히 보호합니다. 골든은 정상으로 알려진 기준선으로부터의 리그레션을 막아 줄 뿐, 그 기준선이 올바랐다는 것을 입증하지는 않습니다. 그것은 유닛, 구조, 적합성 계층의 역할입니다.
한계와 경계
섹션 제목: “한계와 경계”골든 테스트는 정확히 하나의 질문에 답합니다. 출력이 고정된 참조에서 바뀌었는가입니다. 그것은 참조가 애초에 올바랐는지는 말해 주지 않습니다. 또한 성능, 적합성, 보안을 측정하지도 않습니다. 그것들은 다른 계층의 몫입니다. 픽스처 코퍼스의 크기, 스위트의 통과율, 그리고 모든 커버리지 수치는 지속적 통합 아티팩트에서 생성되어 빌드와 함께 공개되는 살아 있는 품질 신호입니다. 이들은 낡아 버릴 수 있는 곳에 두지 않으려고 여기에는 의도적으로 기재하지 않습니다.
정확한 디렉터리 레이아웃, 비교기 내부, 갱신 스위치는 엔진의 테스트 인프라가 소유하며 변할 수 있습니다. 이 설명과 어긋나는 경우 테스트 구성이 권위 있는 근거입니다. 이 페이지는 다른 라이브러리의 스냅샷이나 골든 도구에 대해서는 어떠한 주장도 하지 않습니다.
관련 문서
섹션 제목: “관련 문서”- NextPDF 테스팅 피라미드 — 다섯 계층 가운데 골든 계층이 어디에 자리하고 무엇을 고유하게 증명하는지 설명합니다.
- 뮤테이션 테스트 설명 — NextPDF가 골든을 포함한 자신의 테스트가 실제로 결함을 검출하는지 어떻게 확인하는지 설명합니다.
- 어디서나 엄격한 타입 — 골든이 실행되기도 전에 한 부류의 결함을 제거하는 정적 분석입니다.
용어집
섹션 제목: “용어집”- 골든 파일 — 정상으로 알려진 엔진 동작에서 생성되어 커밋된, 고정된 참조 출력으로, 테스트가 실행할 때마다 이것과 차이를 비교합니다. 결코 자동으로 갱신되지 않습니다.
- 2계층 차이 비교 — NextPDF의 골든 비교. 원시 바이트 대신 추출된 텍스트(Layer 1)와 정규화된 구조 연산자(Layer 2)를 사용합니다.
- 스냅샷 테스트 — 관련이 있지만 별개인 기법으로, 참조가 첫 실행 시 다시 생성되고 드리프트는 갱신 플래그를 통해 받아들여집니다.
- 특성화 테스트 — 기존 동작이 올바르다고 단언하지 않으면서 그것을 고정하는 테스트로, 보통 리팩터링을 안전하게 만들기 위해 사용됩니다.
- 재현성 프로파일 — 출력이 재현되어야 하는 수준입니다. bitwise(정확한 바이트), structural(객체 그래프와 연산자 시퀀스, 무해한 바이트 편차는 허용), semantic(의미) 중 하나입니다. 여기서 다루는 골든 테스트는 구조적 프로파일을 단언합니다.
GOLDEN_UPDATE— 골든 참조의 덮어쓰기를 허가하는 명시적인 환경 스위치입니다. 드물고 검토를 거치는 작업입니다.