Вы можете не знать про пирамиду тестирования. Но если вы строите AI-ассистента для QA — пирамида обязательно узнает про вас.
Привет! Это снова Михаил Федоров. Впервой статьея рассказал про архитектуру QA Assist — системы из 11 AI-агентов для автоматизации тестирования. Вовторой— честно показал, как «4 часа подключения» превращаются в неделю корпоративной реальности.
Сегодня поговорим о штуке, которая на первый взгляд не имеет отношения к AI. О пирамиде тестирования. О том, почему классическая теория QA внезапно оказывается критически важной, когда вашим тест-дизайнером становится языковая модель с контекстным окном.
Оглавление
- Быстрое напоминание: что за пирамида
- От архитектуры к тестам: уровни требований
- Как это выглядит на практике: один Feature — три уровня тестов
- А теперь — причём тут AI
- Контекстное окно: слон, который не влезает
- Почему LLM закономерно работает хуже на верхних уровнях пирамиды
- Как это устроено в QA Assist
- Заключение
1. Быстрое напоминание: что за пирамида
Если вы QA — пролистайте этот раздел. Если нет — задержитесь на минуту.
Пирамида тестирования— это модель, которая говорит: тестов разного уровня должно быть разное количество. Внизу — много дешёвых и быстрых. Вверху — мало дорогих и медленных.
Главное правило пирамиды:если цель проверки можно достичь на уровень ниже — сделай это. Не нужно проверять, что backend правильно рассчитывает комиссию, через UI — открывая браузер, логинясь, заполняя форму платежа и сверяя итоговую сумму на экране. Достаточно отправитьPOST /api/paymentsи проверить полеcommissionв ответе. Быстрее, надёжнее, дешевле.
Но это вы и так знаете. Давайте поговорим о том,откуда берутся уровнии почему это не просто «хорошая практика», а следствие архитектуры.
2. От архитектуры к тестам: уровни требований
Здесь начинается самое интересное. Уровни тестирования — это не абстрактная теория. Они напрямую вытекают из архитектуры продукта и уровней требований.
В любой более-менее серьёзной разработке (привет, SAFe, но не пугайтесь — мы без фанатизма) есть иерархия:
Уровень требований
Уровень архитектуры
Задачи в Jira
Что тестируем
Бизнес-требования
IT-решение
Epic / Feature
Сквозные бизнес-процессы
Пользовательские требования
Информационная система
User Story
Сценарии взаимодействия пользователя
Функциональные требования
Функции отдельных модулей
Каждый уровень архитектуры — это свой уровень тестирования. И каждый отвечает на свой вопрос:
Точка тестирования
Метод работает правильно?
Класс/интерфейс
Компонент выполняет свои функции?
Компонент (back, web, mobile)
API компонента, UI компонента
Система правильно обслуживает пользователя?
Информационная система
API системы, UI системы
Бизнес-процесс работает от начала до конца?
IT-решение
E2E через все системы
«Ну и что?» — скажете вы. «Я это в книжке читал». Окей, давайте перейдём от теории к конкретике.
3. Как это выглядит на практике: один Feature — три уровня тестов
Возьмём простой пример. Feature:
Промокоды при оформлении заказа
Пользователь может ввести промокод при оформлении заказа и получить скидку. Нужно: добавить поле на форму, реализовать логику расчёта скидки на backend, отобразить итоговую сумму, показать применённый промокод в истории заказов и в админке.
Архитектурно это затрагивает несколько компонентов:
Требования тоже выстраиваются по пирамиде — от общего к частному:
- Feature(бизнес-требование): «Поддержка промокодов при оформлении заказа» — что нужно бизнесу
- User Stories(пользовательские требования): «Применение промокода», «История заказов», «Управление промокодами в админке» — что делает пользователь
- Tasks(функциональные требования): Back — эндпоинты, валидация, расчёт скидки; Web — форма, отображение, обратная связь — что делает каждый компонент
Каждый уровень требований порождает свой уровень тестов. Посмотрим на примере US «Применение промокода».
User Story:
Как покупатель, я хочу ввести промокод при оформлении заказа, чтобы получить скидку.
Task: Back — API промокодов:
Реализовать эндпоинтPOST /orders/apply-promo. Принимает код промокода, валидирует (существует, не просрочен, не превышен лимит), рассчитывает скидку, возвращает итоговую сумму. При ошибке —400с описанием причины.
Task: Web — форма промокода:
Добавить поле «Промокод» и кнопку «Применить» на страницу оформления заказа. Валидация формата на клиенте: только латиница и цифры, от 4 до 20 символов. После применения — отобразить размер скидки и пересчитанную сумму. При ошибке — показать сообщение под полем.
Уровень 1: Компонентные тесты (Task)
Task: Back — API промокодов
Тестируем backend изолированно, через API-клиент. Несколько примеров из десятков возможных:
Что проверяем
Расчёт скидки
POST /orders/apply-promoс кодомSALE10→ скидка 10% в ответе
Невалидный промокод
POST /orders/apply-promoс просроченным кодом →400 Bad Request
Граничные значения
POST /orders/apply-promoсо скидкой 100% → итог 0, а не отрицательная сумма
Обратная совместимость
POST /ordersбез промокода →200, ничего не ломается
Комбинации типов скидок, лимиты использования, параллельные запросы и т.д.
Task: Web — форма промокода
Тестируем фронтенд изолированно. Примеры:
Что проверяем
Отображение
Поле «Промокод» видно, кнопка «Применить» активна
Валидация формата
Ввод кириллицы или спецсимволов → ошибка, не отправляя запрос на сервер
Обратная связь
После ввода валидного кода → отображается размер скидки и новая сумма
Невалидный код → сообщение об ошибке под полем
Граничные длины (3 и 21 символ), состояния загрузки, повторное применение и т.д.
Обратите внимание: цели этих проверок таковы, что для их выполнения нам нужен только сам компонент. Всё остальное можно замокировать — и это не повлияет на результат, а наоборот, только облегчит работу с тестовыми данными.
Уровень 2: Системные тесты (User Story)
US: Применение промокода при оформлении заказа
Проверяемпользовательский сценарий целикомвнутри одной системы. Например:
Что проверяем
Сценарий от начала до конца
Добавить товар → ввести промокод → оформить → заказ создан со скидкой
Интеграция front↔back
Сумма на экране совпадает с тем, что вернул API
Данные сохранились
Промокод и скидка записаны в заказе в БД
Негативные сценарии, альтернативные пути, разные роли пользователей и т.д.
Обратите внимание: на этом уровне мы уже уверены, что каждый компонент по отдельности соответствует своим требованиям — это проверено на уровне 1. Теперь нужно убедиться, что интеграционные сценарии уровня User Story работают корректно. Кроме того, у системного уровня могут быть свои уникальные требования, которых нет ни в одном компонентном Task — например, сквозной пользовательский путь или согласованность данных между front и back.
Уровень 3: E2E-тесты (Feature)
Feature: Промокоды при оформлении заказа
Когда все User Stories протестированы на своём уровне, проверяемвзаимодействие между ними. Например:
Что проверяем
Заказ + История
Оформили заказ с промокодом → в истории заказов видна скидка
Заказ + Админка
Оформили заказ → в админке отображается применённый промокод
Админка + Заказ
Деактивировали промокод в админке → при оформлении он больше не работает
Кросс-системные сценарии, цепочки действий между разными ИС и т.д.
Видите разницу? На каждом уровне —свой объект,свой контекст,свои проверки. Компонентный тест не знает про админку. Системный тест не знает про историю заказов. И это не баг — это фича.
4. А теперь — причём тут AI
Вот мы и добрались до главного. Всё, что выше, — классика QA-теории. Её преподают на курсах, спрашивают на собеседованиях и... часто игнорируют на практике. Потому что «у нас не хватает времени на правильную декомпозицию» и «давайте просто напишем E2E и покроем всё разом».
Но когда вашим тест-дизайнером становится AI-ассистент, пирамида тестирования из «хорошей практики» превращается вархитектурное ограничение. И вот почему.
Контекстное окно: почему размер имеет значение
У любой языковой модели есть контекстное окно — максимальный объём информации, который она может удерживать «в голове» за один раз. У Claude — на момент написания — до миллиона токенов. Звучит внушительно, правда?
Давайте посчитаем. Представьте Feature масштабом посерьёзнее наших промокодов — например, доработка платёжной системы: 12 User Stories, ~40 Tasks, к каждому — API-контракт, макеты, тестовые данные, бизнес-правила.
Если попытаться запихнутьвсё этов один промпт и попросить модель «сгенерировать тесты» — произойдёт одно из двух:
- Не влезет физически.Полное описание Feature с контрактами, макетами, тестовыми данными и контекстом легко перешагивает за лимит.
- Влезет, но качество просядет.И это даже хуже, чем первый вариант. Модель не скажет «я не справляюсь» — она просто начнёт срезать углы. Пропустит граничные значения. Упростит негативные сценарии. «Забудет» про обратную совместимость. Результат будет выглядеть правдоподобно, но по факту — покроет 60% вместо 95%.
Это как попросить человека одновременно запомнить 12 рецептов и по каждому проверить свежесть ингредиентов, время готовки и совместимость с аллергиями. Он кивнёт, начнёт уверенно — и где-то на седьмом рецепте перепутает соль с сахаром.
5. Контекстное окно: слон, который не влезает
Давайте визуализируем проблему:
А теперь — после декомпозиции по пирамиде:
Вместо одного слона — много маленьких кусочков торта. Каждый — в своём контексте, со своими данными, со своим фокусом. Модель работает с одной задачей за раз и делает этокачественно.
Это не хитрость и не лайфхак. Это прямое следствие пирамиды тестирования:разные уровни тестов требуют разного контекста. Компонентному тесту не нужен Figma-макет соседнего компонента. Системному тесту не нужны детали валидации каждого поля. E2E-тесту не нужен исходный код backend-сервиса.
Пирамида — это естественная декомпозиция контекста. Причём не просто «на мелкие куски», а направильные куски. Если разбить Feature не по архитектуре, а «по смыслу» — например, «всё про валидацию» или «всё про отображение» — получится мешанина из разных компонентов и уровней. Результат: дубли (одна проверка в двух кусках) и пробелы (интеграция между кусками — ничья зона ответственности). Пирамида решает это: каждый уровень отвечает за свой тип проверки, и требования декомпозированы от Feature через US до Task.
Давайте посчитаем
Визуализация — это хорошо, но хочется конкретики. Прикинем на нашем примере (цифры ниже — порядок величин, не точный расчёт).
Подход «всё в одном»:
- 12 US × ~5 страниц описания = 60 страниц
- 40 Tasks × ~2 страницы = 80 страниц
- API-контракты: ~30 страниц
- Figma-данные: ~20 страниц
- Global Context: ~15 страниц
- Итого: ~205 страниц контекста
Это примерно 150 000 токенов. Вроде бы влезает в миллион? Да. Но помните: чем больше контекста, тем ниже качество. LLM — не база данных, а «внимание» модели распределяется по всему окну.
Подход «по пирамиде»:
Один компонентный тест (Task: Back API):
- Описание Task: 2 страницы
- API-контракт этого сервиса: 3 страницы
- Тестовые данные: 1 страница
- Релевантная часть Global Context: 2 страницы
- Итого: ~8 страниц ≈ 6 000 токенов
Модель работает с 6 000 токенов вместо 150 000. Контекст сфокусирован. Внимание не рассеивается. Качество максимальное.
А таких задач — 40. Но каждая решаетсяточно, а не «примерно».
6. Почему LLM закономерно работает хуже на верхних уровнях пирамиды
В предыдущем разделе мы говорили про размер контекста — «влезет или не влезет». Но проблема глубже. Даже когда всё формально влезает, качество генерациипадает по законам, которые всё лучше изучены.
Важно понимать: эти ограничения влияют на генерацию тестовлюбогоуровня. Но чем выше уровень пирамиды, тем сильнее удар — потому что растёт и объём контекста, и длина цепочек шагов в сценариях. Компонентный API-тест — это 1 эндпоинт, 3-5 шагов, контекст одного сервиса. E2E-тест — это 3 системы, 15-20 шагов, контракты всех сервисов, Figma-макеты нескольких экранов, переходы между состояниями, тестовые данные для каждой точки, роли пользователей, правила авторизации между системами. Разница на порядок.
Давайте разберём три конкретных причины — каждая из них объясняет, почему правильная декомпозиция контекста для AI-ассистента не просто полезна, а необходима.
6.1. Context rot: качество гниёт задолго до переполнения
Вы загрузили в модель 150 000 токенов из миллиона доступных. Используете всего 15% окна. Всё должно быть идеально, правда?
Нет.Исследование Chroma (2025)формализовало явление, которое назвалиcontext rot— «гниение контекста». Суть: качество ответов модели начинает деградировать задолго до того, как окно заполнится. Даже при 15% заполнения качество уже заметно проседает.
Почему? Потому что LLM — не база данных. Механизм внимания (attention) распределяется по всему контексту. Чем больше текста — тем тоньше «размазывается» внимание по каждому фрагменту. Это не баг конкретной модели — это фундаментальное свойство архитектуры трансформеров.
Что это значит для тестирования:
Помните расчёт из предыдущего раздела? Полный контекст Feature — ~150 000 токенов, один компонентный Task — ~6 000. Разница не просто в объёме. Это разница между «модель старается, но мажет» и «модель работает на пике возможностей».
Context rot — это причина, по которой модель «забывает» проверить граничные значения в седьмом Task из двенадцати. Она не глупая и не ленивая. Ей просто не хватает «внимания» — в буквальном, техническом смысле.
6.2. Экономика токенов: пирамида экономит деньги
Давайте поговорим про деньги. Если вы используете API модели, каждый токен стоит денег напрямую. На подписке токены ограничены иначе — часовыми и недельными лимитами: израсходовал бюджет на генерацию E2E-тестов — жди следующего окна.
Прикинем стоимость генерации тестов на нашем примере:
Входной контекст
Итерации отладки
Токенов на 1 тест
Тестов нужно
Компонентный
Посчитаем суммарно:
- 40 компонентных тестов: 40 × 15K =600K токенов
- 12 системных тестов: 12 × 90K =1 080K токенов
- 5 E2E-тестов: 5 × 320K =1 600K токенов
Сравните: 5 E2E-тестов — 1 600K токенов, 40 компонентных — 600K.В 2.7 раза дороже за 5 тестов против сорока.При этом 40 компонентных тестов покрывают значительно больше проверок — просто на другом уровне.
Ключевой множитель —итерации отладки. Компонентный тест обычно работает с первого-второго раза: контекст маленький, модель не путается, тест запускается мгновенно. E2E-тест — 3-5 итераций: модель ошибается чаще (context rot), тест запускается минуты, каждая итерация — это повторная загрузка контекста и новая генерация.
Пирамида — это не только про архитектуру. Это простоимость владения тестами в мире, где генерация стоит денег.
6.3. Поддержка: чинить тесты тоже должен AI
Тесты — это код, и он ломается при изменениях. Кнопку переименовали, эндпоинт переехал, бизнес-правило изменилось — тесты падают. Вопрос не в том,упадут лиони, а в том,сколько контекста нужно AI-ассистенту, чтобы их починить.
Изменилась логика расчёта скидки на бэкенде — промокод теперь применяется после налога, а не до:
- Без пирамиды: упали E2E-тесты, которые проверяют итоговую сумму. Ассистенту нужно загрузить весь сценарий (20 шагов, 3 системы), понять что именно сломалось — фронт? бэк? данные? — и только потом починить assert
- С пирамидой: упали 2-3 компонентных API-теста, которые проверяют именно расчёт скидки. Ассистент загружает контекст одного сервиса, видит что изменилась формула, обновляет ожидаемые значения. Фокус узкий, причина очевидна
Это тот же context rot, только на этапе поддержки: чем больше контекста нужно для починки — тем ниже качество фикса. Компонентный тест — точечный фикс с минимальным контекстом. E2E — расследование, где ассистенту нужно загрузить всё: код теста, сценарий, требования, историю изменений, контракты нескольких сервисов. И чем больше этого контекста — тем выше шанс, что фикс окажется неточным.
Чем ниже уровень теста, тем меньше причин для его поломки и тем меньше контекста нужно AI для починки.
Итог: чем выше уровень — тем больше проблем складывается вместе
Каждая из трёх причин влияет на генерацию тестов любого уровня. Но на верхних уровнях пирамиды онинакапливаются:
Компонентный тест
~6K токенов, 1 сервис
~80K токенов, 3+ системы
Context rot
Минимальный
Значительный
Поломка локализована, фикс точечный
Поломка размазана, нужен весь контекст
E2E-тесты объективно сложнее для любого исполнителя — и для человека, и для AI. Но ограничения LLM эту сложностьусугубляют: большой контекст деградирует, длинные цепочки шагов увеличивают вероятность ошибки на каждом звене, медленная обратная связь не даёт быстро исправиться. В результате вероятность получить некачественный E2E-тест значительно выше, чем компонентный.
Вывод: чем больше тестов на нижних уровнях пирамиды — тем меньше вы зависите от слабых сторон LLM.
7. Как это устроено в QA Assist
Теперь давайте посмотрим, как пирамида тестирования встроена в архитектуру нашего AI-ассистента. Это не теоретический фреймворк — это конкретные решения в коде, которые определяют, как система работает.
Декомпозиция требований — точка входа
Первый агент в пайплайне —requirements-decomposer— не просто «разбивает текст на куски». Он декомпозирует требованияв соответствии с архитектурой продукта, типизируя каждую задачу. При этом не важно, позаботились ли аналитики о разделении на уровни — агент знает архитектуру системы из Global Context и сам раскладывает требования по полочкам:
Каждый уровень получаетсвоюсистему идентификаторов требований:
- User Story:F-DEVAI-283-01,AC-DEVAI-283-01
- Backend Task:F-DEVAI-283-BE-01,AC-DEVAI-283-BE-01
- Frontend Task:F-DEVAI-283-FE-01,AC-DEVAI-283-FE-01
Обратите внимание на суффиксы-BE-,-FE-. Это не просто маркировка — это ключ к тому, как дальше работает вся система. Генератор сценариев видитTASK-*-BE-*и знает: это компонентный API-тест. ВидитUS-*— это E2E. Никакой магии, просто конвенция.
Генерация тестов — три уровня, три типа файлов
Агентscenarios-generatorгенерирует сценариистрого по уровням, и каждый уровень — это отдельный JSON-файл со своими правилами:
Требование
Файл сценария
Зависимости
US-{id}.md
US-{id}-SC-E2E.json
Без моков — все сервисы реальные
TASK-{id}-FE.md
TASK-{id}-SC-UI.json
Backend замокан:MOCK: POST /api/...
TASK-{id}-BE.md
TASK-{id}-SC-API.json
Внешние сервисы замоканы
Ключевое различие — в полеtestScope. E2E-тесты работают с реальной системой. Изолированные — мокают зависимости. И это не просто метаданные — автоматизаторы (automation-apiиautomation-ui) фильтруют сценарии по полямlevelиtestScope. Каждый автоматизатор работаеттолько со своимисценариями. Не видит чужих. Не путается. Контекст минимальный.
Контекст — каждому уровню своё
Модель загружает разный контекст в зависимости от того, что генерирует:
API-тест (isolated, level: api):
- Описание Backend-Task
- OpenAPI-контракт конкретного сервиса из Global Context
- Тестовые данные (test_data.yaml)
- Список эндпоинтов (services_endpoints.yaml)
- Figma? Не нужна. Не загружается.
UI-тест (isolated, level: ui):
- Описание Frontend-Task
- Figma-данные (FIGMA_DATA.json) — элементы, формы, состояния
- Селекторы (SELECTORS.json) — собранные из реального DOM
- Тестовые данные
- API-контракт? Нужен только для моков — загружается частично.
E2E-тест (e2e, level: ui):
- Описание User Story + Acceptance Criteria
- Оба типа контекста, но на уровне сценариев, а не деталей
- Без моков — все сервисы реальные
8. Заключение
Вернёмся к вопросу из заголовка:нужно ли QA-ассистенту знать про пирамиду тестирования?
Не просто «нужно» — без неё AI-ассистент превращается из полезного инструмента в генератор правдоподобного мусора. Пирамида решает три фундаментальные проблемы:
1. Контекст.Большую задачу нельзя скормить модели целиком — качество деградирует. Причём деградирует не на пределе, а задолго до него — это явление context rot. Пирамида — естественный способ декомпозиции: каждый уровень = свой контекст, свой фокус, свой объём. Слон режется на кусочки не произвольно, а по архитектуре.
2. Стоимость.Генерация, отладка и поддержка E2E-теста обходятся в разы дороже компонентного — и по токенам, и по итерациям. Пирамида позволяет покрыть больше проверок меньшими затратами.
3. Поддержка.Тесты ломаются, и чем ниже уровень — тем меньше причин для поломки, тем проще фикс и тем меньше контекста нужно агенту для починки. Компонентный тест — точечный фикс за секунды. E2E — расследование с загрузкой всего контекста.
Очевидные возражения: «А почему не RAG — подтягивать нужный контекст динамически?» — RAG помогает, но не снимает проблему декомпозиции требований. Даже если модель получает релевантные фрагменты, ей всё равно нужно понимать, на каком уровне она работает и какие проверки уместны. «А если модели станут лучше, пирамида станет не нужна?» — даже с ростом контекстных окон пирамида остаётся полезной как принцип фокусировки: меньше контекста = выше качество, и это свойство архитектуры трансформеров, а не временное ограничение.
Вот ирония: теория, которую многие считают «академической» и «для собеседований», оказаласьинженерным фундаментомдля работы AI в тестировании. Не потому что так написано в книжке. А потому что контекстные окна — конечные, токены — не бесплатные, а время — не резиновое.
Если вы строите AI-ассистента для QA (или просто организуете тестирование в команде) — начните с правильной декомпозиции. Пирамида не устарела. Она, наоборот, стала актуальнее, чем когда-либо.
Предыдущие части:
- Часть 1: Как мы построили AI-экзоскелет для QA-инженера
- Часть 2: Возможно ли запустить AI-тестирование за 4 часа?
Источники:
- Context Rot: How Increasing Input Tokens Impacts LLM Performance— Chroma Research, 2025