Мастер-чеклист «как тестировать что угодно» — frontend/UI и backend/сервисы. Доктрина:
- Дотошность по умолчанию. Покрывай всё сам: happy path → негатив → границы → редкие комбинации. Глубина пропорциональна риску, но классы проверок не пропускай.
- Доказательность. Pass/Fail ставится ТОЛЬКО по наблюдённому артефакту (скриншот, ответ сети, лог, дамп БД). Не проверял —
Not tested, помешали —Blockedс причиной. Никаких галлюцинаций и «по логике должно работать». - Логируй каждое отклонение сразу. Любое расхождение с макетом/требованиями фиксируй немедленно, даже минорное (отступ, копирайт, цвет).
- Цель — заменить ручное тестирование. Надёжность важнее скорости; «не успел/не смог» пишем прямо.
0. Процесс (для любой задачи)
Сбор контекста
- Прочитать тикет целиком: описание, AC/Gherkin, комментарии, вложения, связанные задачи (blocks/relates/epic), компонент, релиз.
- Зафиксировать source of truth для каждого требования (AC → ТЗ/Confluence → Figma → прод-поведение) и приоритет при конфликте.
- Сверить Figma: версия, режим (desktop/mobile/adaptive), states (default/hover/focus/active/disabled/loading/error/empty), варианты компонентов, токены; что в макете vs что «подразумевается».
- Найти существующие ТК (в вашей TMS — Zephyr/TestRail/др.) и автотесты (в репозитории автотестов проекта): переиспользовать, выявить пробелы, не дублировать. Статусам TMS не верить слепо — сверять с живыми тестами: встречаются «Automated» без существующего автотеста и «требуется автоматизация» на давно покрытом.
- Снять прод/preprod baseline (как фича работает сейчас — для регрессии и воспроизведения багов на актуальной версии).
- Уточнить окружение: стенд, доступы, тестовые учётки/роли, фиче-флаги, состояние данных, версия билда/коммит.
- Определить интеграции и зависимости: внешние API, платёжки, авторизация, очереди — что мокается, что реально.
- Явно зафиксировать out of scope (нативные приложения, неподдерживаемые браузеры, легаси-флоу).
Анализ требований и вопросы аналитику
- Каждый AC → проверка; каждая проверка → ссылка на AC или явная пометка «доп. эвристика».
- Когда скоуп = конкретное ТЗ: вердикты Pass/Fail только по его пунктам; находки вне ТЗ — отдельным блоком «вне скоупа» (наблюдение/вопрос), не Fail и не дефект задачи.
- Выявить неоднозначности («должно корректно работать», нет конкретных значений, неуказанные границы, неопределённое поведение при ошибке).
- Расхождения тикет ↔ Figma ↔ прод ↔ доку — НЕ закрывать допущением, выписать вопросом.
- Зафиксировать неопределённое поведение: пустые состояния, ошибки сети/сервера, таймауты, отказ интеграции, параллельные действия, истёкшая сессия.
- Уточнить: валидации (обязательность, форматы, маски, длины, допустимые символы, клиент vs сервер, тексты ошибок); права/роли (кто видит/может, неавторизованный, без permission); локаль/форматы (язык, дата/время/валюта/числа, TZ, направление текста).
- Все вопросы — списком с пометкой блокирующий/неблокирующий; блокирующие закрыть до старта.
Приоритизация и риск
- Риск по областям = вероятность дефекта × влияние (деньги, безопасность, данные, репутация, частота использования).
- Фокус на изменённом коде и его blast radius, а не ровным слоем.
- Решить: что автоматизировать (стабильное, регрессоопасное) vs ручная проверка (разведка, UX, разовое, визуал).
- Выделить smoke-подмножество (критичное для быстрой проверки билда) и regress-подмножество.
- Под дедлайн договориться о глубине явно, а не молча урезать.
План / матрица покрытия
- Scope: что входит/нет, на каких окружениях/браузерах/вьюпортах.
- Матрица: браузеры (Chromium/WebKit/Firefox) × вьюпорты × роли × состояния данных.
- Классы проверок: функциональные (happy/negative/boundary), UI/верстка/адаптив, валидации, навигация/роутинг/deeplink, состояния (loading/empty/error/success), доступы/роли, интеграции/API, данные/персистентность; нефункциональное (перф, security) где релевантно.
- Для каждого пункта: предусловие → действие → ожидаемый результат → привязка к AC/источнику.
- Тестовые данные: валидные/невалидные/граничные, спецсимволы, длинные строки, пустые значения, разные роли/состояния аккаунта.
- Согласовать exit-критерии и формат отчёта ДО выполнения.
Выполнение (доказательно)
- Масштаб прогона. Крупную задачу (длинный многошаговый флоу, полный регресс экрана, сверка прод/тест, E2E релиза) выполнять через fan-out (
references/fan-out.md): оркестратор последовательно ведёт браузер и собирает артефакты, затем параллельные субагенты (Agent) разбирают их по осям, синтез сводит находки. Мелкую (одна страница, smoke, один баг) — линейным проходом. - ОБЪЁМ ПРОГОНА ОЦЕНИВАЕТСЯ ДО СТАРТА, А СПОСОБ ИСПОЛНЕНИЯ СОГЛАСОВЫВАЕТСЯ. Прежде чем начать, посчитай объём: сколько ТК, сколько шагов, сколько разрешений/браузеров. Если объём тянет на fan-out (ориентир: >10 ТК, полный регресс экрана, длинный E2E) — предложи это пользователю явно и назови альтернативу с оценкой. Запрет самостоятельно запускать субагентов не запрещает их ПРЕДЛАГАТЬ: решение за пользователем, вопрос стоит десяти секунд. Молча уйти в линейный проход и упереться в контекст на середине — провал планирования: прогон встанет незаконченным, а пользователь узнает об этом постфактум. Тот же принцип для любого ограничения, способного сорвать задачу на середине (нет тестовых данных, лежит стенд, недоступна интеграция, нужен доступ) — озвучивать на старте, а не когда упёрся.
- Линейный проход — тоже решение, и его цена считается заранее. Один ТК ≈ чтение карточки + 2-4 браузерных вызова + скриншоты; скриншот как изображение дороже всего остального. Не помещается по прикидке — не начинай в надежде «успею», а сокращай методику осознанно и скажи об этом.
- При fan-out разводи агентов по РАЗНЫМ браузерным серверам (playwright / webkit / ios / chrome-devtools и т.п.) и пиши это в промпте каждому: параллельные агенты на одном браузере дерутся за вкладку и портят друг другу прогон. Передавай агенту карту страницы (рабочие селекторы, квирки, известные дефекты) — иначе каждый заново потратит время на discovery.
- Прибирай за собой, и проверяй уборку по процессам. По завершении прогона закрой браузеры (все MCP, которые открывал), сними моки (
unrouteAll), останови поднятые серверы, удали временные файлы. Оставленные сессии висят фоном и мешают следующему прогону.- В headless-режиме забытый браузер невидим — его не заметит ни пользователь, ни ты. Поэтому уборка заканчивается не вызовом закрытия, а проверкой списка процессов по маркерам автоматизации (
--allow-pre-commit-input,--disable-field-trial-config,--inspector-pipe): пустой вывод = чисто. Личный браузер пользователя этих флагов не имеет и под фильтр не попадает. - Не у всех браузерных MCP есть закрытие браузера (у некоторых только закрытие вкладки, а последнюю вкладку закрыть нельзя) — там уборка только через завершение процесса браузера по маркеру автоматизации или пути временного профиля, НЕ убивая сам MCP-сервер.
- Уборка обязательна и после промежуточных прогонов внутри задачи (проверка гипотезы, воспроизведение бага), а не только в самом конце: контексты, созданные программно, живут в браузере до закрытия.
- В headless-режиме забытый браузер невидим — его не заметит ни пользователь, ни ты. Поэтому уборка заканчивается не вызовом закрытия, а проверкой списка процессов по маркерам автоматизации (
- Воспроизводить по шагам; для каждого результата — наблюдаемый артефакт (скриншот, видео, ответ сети, консоль, дамп DOM/БД).
- Различать: «работает как ожидалось» / «баг» / «вопрос к требованиям» / «не воспроизводится» — не сваливать в одно.
- ИНСТРУМЕНТ ИЗМЕРЕНИЯ ВРЁТ ЧАЩЕ, ЧЕМ ПРОДУКТ. Селектор/регулярка/скрипт — сами объект проверки, а не источник истины. Реальные промахи: регулярка
/Проверьте/поймала подзаголовок «Проверка номера» вместо ошибки; поиск модалки по фразе совпал с тем же текстом в баннере и дал «модалка открыта» там, где её не было;innerTextс переносами строк не совпал с эталоном на корректном экране; фильтр отсёк часть сообщений, и вместо шести ошибок насчиталось одно.- Любой неожиданный результат — сначала проверить измеритель, потом продукт. «Ничего не нашлось», «нашлось не то», «нашлось одно вместо шести», «элемент не найден» — это в первую очередь гипотеза о селекторе.
- Подтверждать глазами то, что посчитал скриптом. Скриншот и текст на нём — арбитр; DOM-выборка доказывает уже увиденное.
- Совпадение по подстроке — ненадёжно. Уникальные фразы целиком, привязка к контейнеру (искать ошибку внутри блока поля, а не по всей странице), проверка количества найденного, а не только факта. Тексты с переносами сравнивать нормализованно.
- BLOCKED СТАВИТСЯ, КОГДА ТК НЕВОЗМОЖНО ВЫПОЛНИТЬ, А НЕ КОГДА ИЗВЕСТНО, ЧТО ОН УПАДЁТ. Если шаги выполнимы и объект доступен — прогнать и поставить Fail с доказательством, даже если дефект уже заведён и результат предсказуем. Blocked — только когда нет доступа, данных или окружения. Ошибочный Blocked прячет ТК из прогона и создаёт ложное «непокрыто»: так два ТК на проверку статуса простояли непрогнанными, хотя падали за минуту и давали готовое доказательство для смежной команды.
- ПЕРЕД «ЭТО ПРОВЕРИТЬ НЕЛЬЗЯ» — ИНВЕНТАРИЗАЦИЯ ТОГО, ЧТО УЖЕ ЕСТЬ. Посмотреть рабочую папку задачи, ранее собранные артефакты, скрипты и моки, свои прошлые заметки и память проекта: нужный инструмент часто уже написан в этой же задаче. Реальный случай: ТК объявлен непроверяемым «нужен мок-сервер», а мок-сервер лежал в папке проекта, написанный неделей раньше в рамках той же задачи. Формулировка «невозможно» допустима только после проверки доступного.
- Проверять не только UI, но и сеть (статус-коды, payload, обработку 4xx/5xx, ретраи, отсутствие чувствительных данных) и персистентность (перезагрузка, повторный вход).
- Консоль держать открытой весь прогон: ошибки/ворнинги JS, 404 ресурсов, CSP/CORS.
- Состояние после действия проверять в нескольких слоях: UI ↔ сеть ↔ БД/хранилище.
- Изолировать дефект: минимальные шаги, частота (always/intermittent), окружение, билд, предусловия; при нестабильности — повторить N раз, зафиксировать частоту, не маскировать ретраем без понимания причины.
- ВВОД ВСЕГДА РЕАЛЬНЫЙ — это дефолт, а не частный случай. Любое значение в любое поле вводится так, как это делает пользователь: клик по полю → посимвольный набор с клавиатуры (
pressSequentially,keyboard.press,insertText) → уход фокуса кликом или Tab. Выбор в списках — кликом по опции, чекбоксы/радио — кликом по видимому контролу, файлы — через реальный диалог. Программная установка (fill(),setInputValue,.value=, native setter +dispatchEvent, автоматизационный «type» поверх них) обходит событийный пайплайн приложения — фреймворковыеonChange/onBlur, маски, дебаунсы, кастомные компоненты, коммитящие значение только кликом по опции.- Оба направления ошибки одинаково опасны. Программный ввод даёт и ложный Fail (в поле текст есть, state пуст → «required» на заполненной форме), и ложный Pass — валидация просто не запускается, и невалидное значение выглядит принятым. Второе хуже: так заводится несуществующий дефект, а реальный остаётся ненайденным.
- Программный ввод допустим ТОЛЬКО для подготовки предусловий — быстро добить неинтересные поля, чтобы дойти до проверяемого шага. Поле, которое проверяешь прямо сейчас, заполняется реальным вводом всегда, без исключений.
- Уход фокуса — тоже реальное действие.
dispatchEvent(new Event('blur'))иel.blur()НЕ эквивалентны настоящему Tab или клику мимо поля: React слушаетfocusoutчерез собственную систему событий, синтетическийblurдо обработчика не доходит. Поле уводится из фокуса только реальнымTabили кликом по другому элементу. Это отдельная ловушка: поля с live-валидацией (email, телефон, дата) на программный blur ошибку всё-таки покажут, а поля, валидируемые на blur (ФИО, латиница), — нет. Получается пёстрая картина, где часть проверок «работает», и легко решить, что метод корректный. - Вердикт Pass/Fail по валидации, маске, required, границе или формату, полученный программным вводом или программным blur, недействителен. Не «подтверждать при сомнении», а не выставлять вовсе, пока не повторил руками. Если результат зависит от способа ввода — это находка про способ ввода, а не про продукт.
- «Ошибки нет» — самый подозрительный результат. Прежде чем писать «валидация отсутствует», обязательно повтори кликом + посимвольным вводом + Tab. Отсутствие ошибки почти всегда означает, что до валидатора не дошло событие, а не что валидатора нет.
- «ЭЛЕМЕНТА НЕТ» — ЭТО УТВЕРЖДЕНИЕ ОБО ВСЕХ СОСТОЯНИЯХ, А НЕ О ТОМ ОДНОМ, В КОТОРОМ ТЫ ПОСМОТРЕЛ. Прежде чем писать «крестик/кнопка/подсказка/иконка не отображается», перебери состояния, в которых элемент может появляться: фокус и потеря фокуса, ховер, пустое и заполненное значение, до и ПОСЛЕ первого успешного действия (проверки, отправки, загрузки), после ошибки, разные вьюпорты. Условие показа часто дизъюнкция («после проверки ИЛИ по потере фокуса»): проверил одну ветку и не нашёл — значит не нашёл в одной ветке, а не «нет вообще». Реальный случай: крестик очистки объявили дефектом, потому что при фокусе его нет; на самом деле он появляется после первой проверки сертификата либо после блюра — обе ветки просто не проверили.
- Красный флаг: пользователь или разработчик говорит «оно же есть», а у тебя нет. Это почти всегда значит, что ты смотрел в другом состоянии, а не что у них показалось. Не спорь и не настаивай на своём замере — выясни, при каких условиях видят они, и воспроизведи ИМЕННО их сценарий.
- Описывая поведение элемента в отчёте или ТК, давай матрицу состояний, а не одну строчку: «при фокусе нет / после блюра есть / после проверки есть» — иначе следующий прогон снова заведёт ложный дефект.
- НАХОДКА СУБАГЕНТА — ГИПОТЕЗА, ПОКА ТЫ НЕ ПРОВЕРИЛ ЕЁ САМ. Ты видишь вывод агента, но не путь к нему: неверный селектор, кусок картины вместо целого, неточная сверка с макетом выглядят ровно так же убедительно, как настоящий дефект. Перед тем как завести дефект или отдать находку разработчику — воспроизведи её лично своим замером. Особенно если находка звучит как «чего-то нет на экране» или «расходится с макетом» (макет открой и посмотри сам). Прошедшие проверки (Pass) переспрашивать не нужно — перепроверяется то, что пойдёт наружу.
- МОК ПРОВЕРЯЕТ ПОВЕДЕНИЕ, А НЕ СОДЕРЖАНИЕ. То, что ты сам положил в заглушку, находкой быть не может — это эхо твоего мока, а не дефект продукта. Вписал в
route.fulfillтело{"message":"Internal Server Error"}, увидел на экране «Internal Server Error» и завёл дефект «пользователю показывают техническое сообщение» — это круговая логика: подложил данные и сам же их «обнаружил». Так заводится несуществующий дефект и тратится время команды.- На заглушке проверяется только реакция приложения: не виснет ли UI, разблокировались ли поля и кнопка, сохранились ли введённые данные, не показался ли ошибочно экран успеха, ушёл ли повторный запрос, отработал ли ретрай, появилось ли уведомление как факт.
- На заглушке НЕ проверяется: текст сообщения, его формулировка и язык, код ошибки, формат и структура ответа, иконка и цвет — всё это ты задал сам.
- Тексты, коды и форматы проверяются только на реальном ответе системы — живым запросом, воспроизведением настоящего сбоя, либо моком, который повторяет контракт (тексты взяты из документации/свагера/живого ответа, а не выдуманы). Мок с выдуманным телом для выводов о содержании непригоден.
- Перед заведением дефекта по любым данным на экране спроси: откуда это значение? Если оно пришло из твоей заглушки, тестовых данных или подмены — дефекта нет. Дефект есть, только когда значение сформировала система.
- МОК СНЯТ — ЭТО ПРОВЕРЯЕТСЯ, А НЕ ПРЕДПОЛАГАЕТСЯ. Забытый роут превращает всё последующее тестирование в фикцию.
page.unroute(pattern)снимает перехват ТОЛЬКО при побуквенном совпадении строки паттерна: роут, поставленный на'**/api/wb/submit-policy', НЕ снимается вызовомunroute('**/api/wb/**')— Playwright сравнивает строки, а не покрытие URL. Мок остаётся висеть на весь сеанс, и каждый следующий прогон получает подставной ответ, принимаемый за поведение продукта.- Снимать
page.unrouteAll()либо строго тем же паттерном, что ставил. Ставить и снимать — в одном месте, рядом. - После снятия — контрольный запрос, и только потом любые выводы: выполнить проверяемое действие и убедиться, что ответ настоящий (статус, тело, побочный эффект вроде созданной записи).
- КРАСНЫЙ ФЛАГ: инструмент и браузер расходятся при идентичном запросе. curl/API-клиент даёт 200, а браузер — 5xx, payload и заголовки совпадают побайтово → в 99% случаев это твой перехват, а не дефект. Первым делом снять все моки и повторить, и лишь потом искать причину в продукте, прокси, CORS или сети.
- Не разворачивать многошаговый разбор дефекта, пока не подтверждено, что окружение чистое. Сравнение заголовков, гипотезы про Origin и инфраструктуру — всё это впустую, если сверху висит собственная заглушка. Сначала докажи, что видишь настоящую систему.
- Между сценариями окружение возвращается в исходное: снятые роуты,
setOffline(false), восстановленные throttling/permissions/storage. Любая незакрытая подмена «протекает» в следующие проверки и портит их незаметно.
- Снимать
- Карта действий (page map) — не переизучать страницу. Первый проход по экрану — исследование; всё найденное (рабочие селекторы, порядок кастомных контролов, эндпоинты API, DOM-квирки, baseline шума консоли стенда) сразу фиксировать в заметку прогона/проекта. Последующие проверки на том же экране выполнять по карте без повторного discovery; повторяющиеся флоу (дойти до шага N визарда) оборачивать в скрипт-хелпер и вызывать одним действием. В начале нового прогона перепроверить 1–2 ключевых селектора карты на живой странице — могли устареть.
- Инструментарий браузерных прогонов. Интерактивные шаги — через MCP-браузер (Playwright / Chrome DevTools MCP). Повторяющиеся флоу и скрипт-хелперы из page map — через
playwright-cli(отдельные процессы/профили; масштабируется на параллельных агентов, §7.8). Кросс-браузер: критичные сценарии (вёрстка, скролл, дата-пикеры, фокус/ховер, файловые инпуты) прогонять минимум в двух движках — Chromium + WebKit (MCP-сервер playwright-webkit илиplaywright-cli --browser webkit; при наличии — iOS-эмуляция): заметная часть UI-багов движко-специфична и в одном Chromium не видна. - Обходной путь ≠ прохождение шага. Если целевое действие ТК не выполняется штатным пользовательским способом (клик/тап/ввод) — это Fail (дефект) или Blocked, даже когда технический workaround существует (
focus(), native setter, прямой вызов API). Workaround допустим только чтобы разблокировать ПОСЛЕДУЮЩИЕ проверки, и это явно фиксируется в отчёте; сам заблокированный шаг «зелёным» через обход не делается. - РЕТЕСТ ПОСЛЕ ПРАВОК — СВЕРКА С ДВУМЯ ЭТАЛОНАМИ: с макетом И с предыдущим прогоном. Правка одного свойства двигает соседей: реальный случай — зафиксировали высоту контейнера карусели, и уехали центрирование между кнопками-стрелками и нижний отступ; оба регресса нашёл заказчик, не прогон.
- Диффать координаты с прошлым прогоном. Изменившееся число (x/y/w/h), которое правкой не объясняется, — сигнал регресса, а не шум: «x был 419, стал 360» обязан быть отработан, даже если сам элемент «в порядке».
- Мерить ВЗАИМНОЕ расположение, а не только сам элемент: зазоры до соседей слева/справа, равенство парных отступов, совпадение центров (элемент ↔ контейнер ↔ вьюпорт). Проверка «карточка нужного размера на месте» не ловит, что соседние кнопки теперь на разном расстоянии.
- Открывать глазами скриншот КАЖДОЙ проверенной ширины и состояния. Снятый, но не открытый скриншот = непроверенное состояние; «числа сошлись» просмотр не заменяет.
- Скриншот элемента-контейнера обрезает выступающих потомков (фиксированная высота, transform, отрицательные margin) — на таком снимке контент выглядит «обрезанным», хотя это артефакт съёмки. Для визуальной сверки снимать блок целиком или вьюпорт; скрин элемента — только для точечного зума.
- После фикса перепроверять весь затронутый узел и смежные ТК, а не только шаг, который падал.
Фиксация / DoD
- Каждый ТК со статусом + доказательством: Pass (артефакт), Fail (баг + артефакт), Blocked (причина), Not tested (почему). Blocked ≠ Fail.
- Формат записи результатов в TMS (комментарии, окружение, вложения) — строго по конвенции команды, не изобретать свой; доказательства в любом случае сохраняются в артефактах прогона и сводном отчёте.
- Дефекты заведены, связаны с тикетом, severity/priority проставлены, шаги и артефакты приложены.
- Покрытие сверено с AC: каждый AC закрыт ≥1 проверкой; непокрытые — явно с причиной.
- Прогон зафиксирован: окружение, билд/коммит, браузеры/вьюпорты, дата, исполнитель.
- Регресс затронутых областей выполнен (или осознанно отложен с фиксацией риска); блокеры эскалированы; вопросы связаны.
- Новые/обновлённые ТК внесены в TMS; кандидаты на автоматизацию помечены.
- Не терять находки при обобщении. Любая аномалия, замеченная в ходе прогона (даже если по ходу показалась минорной или «самоустраняющейся»), обязана попасть в итог - багом или вопросом. Вывод «некритично» не даёт права умолчать: пропущенная в отчёте находка = пропущенный дефект. Особенно ложная/зависшая ошибка валидации (см.
references/common-misses). - Негатив-гейт (обязательно). Прогон НЕ Done, пока не покрыты негативные и граничные классы и не сверено с
references/common-misses; в отчёте обязателен раздел «Негатив» с результатом по каждому классу или явной причиной пропуска. «Объект простой/навигационный» — не основание пропускать негатив: happy-path-only прогон считается неполным. - Done = все неблокированные AC проверены с доказательствами, негатив/границы покрыты (или пропуск обоснован), баги заведены, отчёт и статусы ТК актуальны, остаточные риски и непокрытое перечислены честно.
1. Техники тест-дизайна
Классы эквивалентности (EP) — разбить вход на классы (валидные/невалидные/спец: пустое, null, пробелы). Один представитель из каждого валидного класса; КАЖДЫЙ невалидный класс отдельно (разные сообщения = разные классы). Числа: отриц./0/полож./дробные/сверх лимита. Строки: латиница/кириллица/цифры/спецсимволы/эмодзи/RTL/регистр. Перечисления: каждый вариант + вне списка. Файлы: разрешённый/запрещённый/пустой/битый. Даты: прошлое/настоящее/будущее/невалидный формат/несуществующая (31.02).
Граничные значения (BVA) — точные границы ±1. Для [min..max] проверить ровно: min−1, min, min+1, max−1, max, max+1 (не «маленькое/большое»). Длина строки: 0, 1, min±1, max±1. Граница на 0: −1, 0, 1 (счётчики, остатки, корзина). Деньги: 0.00, мин. платёж, мин−0.01, макс, макс+0.01, округление копеек. Дата/время: 23:59:59→00:00:00, последний день месяца, 29.02 високос/невисокос, переход через полночь/год. Пагинация: 0 элементов, ровно страница, страница+1 элемент, последняя неполная. Возраст/срок: ровно 18 (день в день), ±1 день, expiry ровно в момент.
Таблицы решений — для бизнес-правил с комбинациями условий. Условия × правила × ожидаемое действие; покрыть каждую значимую комбинацию (не все 2^n); включить невозможные/противоречивые (система отвергает). Применять для: скидок/тарифов/расчётов, доступа к фиче (роль × флаг × подписка × состояние), доступности submit (поле A × поле B × чекбокс), взаимоисключающих условий.
Переходы состояний (STT) — для сущности с жизненным циклом (черновик→модерация→опубликовано→архив→удалено). Проверить каждый разрешённый переход и КАЖДЫЙ запрещённый (событие в недопустимом состоянии → блок). Переходы по таймауту/системному событию (автоотмена, истечение сессии); действия, недопустимые в текущем состоянии (редактировать опубликованное, оплатить отменённое); циклы/возвраты; состояние после прерывания; конкурентные переходы двух пользователей.
Pairwise / комбинаторика — когда параметров >3 и полный перебор нереален (ОС × браузер × роль × язык × тема). Сгенерировать набор, покрывающий все пары (PICT/allpairspy); вручную добавить критичные бизнес-связки, которые pairwise может пропустить; проверить дефолты каждого параметра.
Error guessing — для зрелой/легаси-функциональности по слабым местам: двойной/тройной клик, отправка до завершения валидации, спецсимволы/инъекции, очень длинный ввод (10k+), вставка большого текста, пробелы/zero-width, эмодзи, autofill, медленная сеть, Back после успеха, F5 на промежуточном шаге, правка payload в DevTools в обход UI, действие с истёкшим токеном.
Дополнительно: причинно-следственный анализ (AND/OR/NOT между условиями, каскадные/зависимые поля); CRUD-матрица как базовый каркас для любой сущности; матрица доступов (роль × действие × ресурс) + проверка серверной защиты. Всегда: позитив (валидные классы, разрешённые переходы) + негатив (невалидные классы, запрещённые переходы, обход UI).
Выбор техники: диапазон/лимит → BVA+EP; много параметров → pairwise; комбинации условий → таблица решений; жизненный цикл → STT; зависимые условия → cause-effect; сущность с данными → CRUD; легаси → error guessing.
2. Справочники (references/) — обязательное чтение по типу задачи
Детальные чек-листы вынесены в references/. До составления плана прочитай целиком (Read) каждый файл, релевантный задаче — не выборочно и не по памяти; план без прочитанного справочника считается неполным.
| Файл | Когда читать | Что внутри |
|---|---|---|
references/frontend.md |
Любая задача с UI | Поля/формы (маски, лимиты, paste/autofill), визуал и все состояния элементов, сверка с Figma, токены, overflow, адаптив и кросс-браузер (канонические разрешения) |
references/backend.md |
API / сервисы / БД / интеграции | HTTP-методы и коды, схемы/контракты, пагинация, идемпотентность, PATCH, БД (целостность, транзакции, конкурентность, миграции), AuthN/AuthZ/IDOR/мультитенантность, очереди/вебхуки/cron, нагрузка и устойчивость, OWASP API Top 10 |
references/cross-cutting.md |
Почти всегда (фронт и бэк вместе) | Сетевые ошибки и моки, consistency UI↔Backend, сессии/storage/мультивкладки, навигация/deeplink, время/TZ/i18n, перф и консоль, security с фронта, файлы/экспорт, поиск/фильтры, платежи, аналитика |
references/artifacts.md |
Перед фиксацией результатов и багов | Доказательства, HAR/консоль, структура баг-репорта, severity vs priority, расхождения с макетом, трекер/TMS, сводный отчёт прогона |
references/common-misses.md |
Всегда — перед финальным отчётом | Чек-лист «частые пропуски»: финальная самопроверка полноты прогона |
references/fan-out.md |
Крупный прогон: длинный флоу, полный регресс экрана, сверка прод/тест | Как дробить дотошный прогон на параллельных субагентов по осям: сбор артефактов оркестратором → fan-out → синтез. Про способ исполнения, не класс проверок |
Минимальные наборы: UI-задача → frontend + cross-cutting (+artifacts при заведении багов); API/бэк → backend + cross-cutting; полный E2E/релиз → все. Крупный прогон / длинный флоу → дополнительно fan-out.md на этапе выполнения. common-misses.md — всегда последним, перед выводом отчёта.
Применяй технику и трек по контексту задачи. Для каждой реальной задачи сверяйся с её требованиями и макетами, а не с этим списком как с истиной — список напоминает классы проверок, но не заменяет AC и source of truth.