Пирамида тестирования 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 : не все критерии покрытия связаны друг с другом, и для стратегии рекомендуется сочетать функциональные и структурные методы. Что важно, то же приложение отмечает, что отношение поглощения между критериями покрытия ничего не говорит об их способности выявлять дефекты — результативность тестирования (ISO/IEC/IEEE 29119-4, §C.2.4). «Больше покрытия» — это не то же самое утверждение, что «тесты лучше».
Evidence: Standard-backed Выбор того, какие именно свойства доказывать, соотносится с характеристиками качества продукта Spec: ISO/IEC 25010 ISO/IEC 25010 : функциональная корректность (модульный, интеграционный) и свойства на уровне файла, которые делают PDF по-настоящему пригодным для дальнейшего использования (структурный, визуальный, эталонный). Модель качества прямо указывает, что разные характеристики важны в разных контекстах использования.
Практический пример
Заголовок раздела «Практический пример»Уровни можно запускать из собственных скриптов движка. Изменение в одном форматтере проверяется на базовом уровне. Изменение в фасаде документа проверяется на нескольких уровнях:
<?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 запускает его с бюджетом ошибок, зафиксированным на нуле.