Тестирование ПО: UI, API, ручное и автоматизированное
Основа — руководство «Качество решает всё: полное руководство по тестированию ПО» (Роман Сурков). Всё, что помечено [вне книги], взято из других источников (список в конце) или общепринятой практики. Подавай это как дополнение, а не как позицию автора.
Когда применять
- «Протестируй фичу / экран / приложение / API», «составь чек-лист / тест-кейсы», «оформи баг».
- Проверка ТЗ, макета Figma или Swagger до разработки (shift-left).
- Выбор, что и как автоматизировать; нагрузочный сценарий; отчёт о готовности релиза.
- Для видеоигр бери скилл
qa-game-testing, а отсюда — общую базу (тест-дизайн, артефакты).
Шаг 0. Определи режим работы
| Запрос | Что выдать |
|---|---|
| Есть ТЗ / макет, кода ещё нет | Ревью требований (шаг 1) + чек-лист, написанный заранее |
| «Протестируй» без деталей | Разложение по «БЛУГИД с ПК» (шаг 2) → чек-лист → тест-кейсы на сложное |
| Живой сайт / приложение доступны | Прохождение проверок, баг-репорты, итоговый TRR |
| API / Swagger / cURL | BINMEN + POISED (шаг 6), коллекция запросов |
| «Что автоматизировать?», флейки, Playwright | План по пирамиде и правила автотестов (шаг 8) |
| Проверка безопасности API | Матрица OWASP API Top 10 (шаг 6) |
| Фича на LLM (чат-бот, генерация) | Слои проверок и эталонный набор (шаг 9) |
| Свободное тестирование новой фичи | Хартии сессий SBTM + SFDIPOT (шаг 2) |
Сначала позитивные проверки (happy path), потом негативные. В позитивных проверки можно объединять, в негативных — один невалидный параметр на одну проверку.
Шаг 1. Тестирование требований (shift-left)
Ошибка дорожает по правилу 1–10–100: правка в ТЗ стоит 1, в коде — в 3–8 раз дороже, найденная QA — в 20–80 раз, на проде — в 100+ раз. Поэтому начинай с документа.
Критерии хорошего требования (на каждое нарушение — комментарий в документе): полнота (описаны крайние случаи и ошибки), непротиворечивость (текст не спорит с макетом), однозначность, корректность, тестируемость («как я это проверю?»), атомарность (одна идея).
Слова-мусор — «быстрый», «удобный», «интуитивный», «гибкий», «адекватный», «при необходимости». Переписывай в измеримое: «поиск быстрый» → «выдача ≤ 1,5 с при 1000 одновременных запросов».
Если ТЗ нет, ожидаемый результат берётся из: макетов и прототипов → конкурентов → законов и регуляторов (GDPR, PSD2) → best practices и здравого смысла (валидация email, rate-limit, маски телефона) → разговора с разработчиком или аналитиком.
Как прожаривать требования: вопросы о границах (максимальная длина, запрещённые символы, обрыв связи, два пользователя жмут одновременно); блок-схема или mind map пути (стрелка, ушедшая в пустоту, — это неописанный сценарий); тест-кейсы прямо во время чтения (не получается написать кейс — нашёлся баг в ТЗ).
Оракулы FEW HICCUPPS [вне книги, М. Болтон и Дж. Бах] — чем ещё доказать, что поведение проблемное, если спецификации нет или она неполна. Продукт должен быть согласован с: Familiar problems (не повторяет известные типы багов), Explainability (поведение можно объяснить), World (не противоречит реальности), History (прошлыми версиями), Image (образом компании), Comparable products (аналогами), Claims (заявлениями: ТЗ, реклама, справка), User desires (разумными желаниями пользователя), Product (сам с собой: одно действие — одно поведение везде), Purpose (назначением), Statutes and standards (законами и стандартами). В баг-репорте называй оракул: «противоречит прошлой версии», «противоречит справке» — так спорить с «это не баг» проще.
Missing Feature: если функции нет и в ТЗ её нет — это не Bug, а Improvement / Feature Request. Споры снимает матрица функциональности: Web — есть, iOS — есть, Android — нет.
Шаг 2. Разложение задачи «Протестируй»
Функциональное тестирование отвечает на вопрос «ЧТО делает», нефункциональное — «КАК». Нефункциональные векторы перебирай по мнемонике «БЛУГИД с ПК»:
- Б — безопасность (XSS, SQL-инъекции, права доступа)
- Л — локализация
- У — удобство (usability)
- Г — графический интерфейс (GUI)
- И — инсталляция (только то, что устанавливается: десктоп, мобайл, консоли)
- Д — доступность (a11y)
- П — производительность (клиентская и серверная)
- К — конфигурация и совместимость
Добавь исследовательские туры Уиттакера для свободного поиска: путеводитель (главные фичи), задворки (редкие настройки), курьер (один объект через все статусы), деньги (корзина и оплата), полуночник (фоновые задачи), мусорщик («Отмена», «Сброс»), навязчивый (100 повторов одного действия), плохой район (исторически проблемные модули), музей (старый, давно не трогавшийся код).
Что вообще есть в продукте — SFDIPOT [вне книги, HTSM Дж. Баха]: Structure (из чего состоит: файлы, модули, сборки), Function (что делает), Data (что вводят, хранят, выводят; пустое, огромное, битое), Interfaces (UI, API, импорт/экспорт, интеграции), Platform (ОС, браузер, железо, внешние сервисы), Operations (как реально используют: частые сценарии, неопытный и злонамеренный пользователь), Time (таймауты, параллельность, порядок событий, часовые пояса, долгая работа). Пройдись по семи словам — получишь карту покрытия, которую БЛУГИД не даёт.
Исследовательское тестирование сессиями (SBTM) [вне книги, Дж. и Дж. Бах]. Сессия 60–90 минут без отвлечений, у неё хартия: «Исследовать <область> с помощью <инструменты, приёмы, данные>, чтобы обнаружить <что хотим узнать>». По итогам — лист сессии: что покрыто, найденные баги, вопросы, риски, доля времени на тестирование / оформление багов / настройку окружения, и короткий разбор с лидом. Так свободное тестирование становится отчётным: видно, что проверено и что осталось.
Шаг 3. Техники тест-дизайна
Порядок: сначала каркас из EP + BVA + таблиц решений, потом усиление через Error Guessing.
- Классы эквивалентности (EP): по одному значению из каждого валидного и невалидного класса.
- Граничные значения — только 3BVA: на каждой границе брать
min-1, min, min+1(и так же для max). 2BVA пропускает опечатку оператораX == 10вместоX >= 10: точки 9 и 10 проходят, а 11 ломается. Пример: доступ 18–100 лет →-1, 0, 1, 16, 17, 18, 99, 100, 101. Для денег шаг — минимальная единица (0,01 ₽). - Комбинаторика: 1-wise (≈50% багов, экспресс), pairwise — стандарт (70–90%), 3-wise для финтеха
(≈95%), полный перебор только для критичных систем. Никогда не собирай pairwise-матрицу в голове:
сгенерируй её инструментом (PICT, если установлен, иначе
pip install allpairspy --break-system-packages) и проверь скриптом, что покрыты все пары. Где применять: фильтры каталога, калькуляторы, оплата × доставка, экспорт (формат × кодировка × разделитель). Для кросс-браузерности pairwise не использовать (см. шаг 5). - Таблицы принятия решений: когда в ТЗ много «если / и / или / кроме», 2–5 бинарных условий. Вычёркивай невозможные комбинации, а правила с одинаковым исходом склеивай в один кейс. Типовые места: скидки и промокоды, матрица ролей, зависимые поля формы (юрлицо → ИНН и КПП обязательны), статусы заказа.
- Состояния и переходы: всё, у чего есть жизненный цикл и таймауты. Проверяй недопустимые переходы, истечение таймаута (бронь без оплаты возвращается в «Свободно»), одноразовость токенов (повторный сброс пароля по старой ссылке), обрыв на каждом шаге.
- Error Guessing — каталог граблей:
- грязный ввод: только пробелы, пробелы по краям email, U+200B, эмодзи, кавычки, иероглифы, 10 000 символов из буфера;
- повторы и гонки: тройной клик «Оплатить», «Назад» после транзакции, последний товар покупают двое;
- прерывания: обрыв сети на 99%, закрытие вкладки во время эквайринга;
- даты и числа: 29.02 в невисокосный год, дата рождения в будущем,
00.00.0000, количество −1, 0, 999 999; - окружение: сессия протухла за 3 часа простоя,
.exeс расширением.jpg, файл на 500 МБ.
Шаг 4. Артефакты
Чек-лист (ID, проверка, статус) — по умолчанию. Тест-кейс — для сложной логики, онбординга и передачи в автоматизацию.
Поля тест-кейса: ID, название, приоритет, предусловие (заполняется всегда), шаги, тестовые данные, ожидаемый результат; после прогона — фактический результат и статус (Passed / Failed / Blocked / Skipped).
Правила: в шагах только действия тестировщика, реакции системы — в ожидаемом результате; шаги атомарные («ввести email», «ввести пароль», «нажать Войти» — три шага); один кейс = одна проверка; кейсы не зависят друг от друга (подготовка уходит в предусловие или делается через API); детализация разумная, без «подвинуть мышь»; приоритет High — деньги и авторизация, Low — косметика, остальное (≈80%) Medium.
Тест-свит — папка по модулю с вложенными свитами по фичам; общие проверки модуля лежат в корне свита. Тест-ран — прогон набора на конкретной сборке и окружении со статусами. Тест-план (по запросу): scope (in / out), стратегия и окружение, критерии входа, приостановки и выхода, ресурсы и сроки, риски с планом Б.
Баг-репорт
Заголовок: [Где] Что происходит, при каком условии
пример: [Окно промокода] ошибка 500 при вводе просроченного купона
Окружение: Prod/Stage, браузер и версия, ОС; для мобайла модель и точная версия ОС; URL
Предусловие: роль пользователя, страница, подготовленные данные
Шаги: 1. … 2. … (только действия, минимальная цепочка)
Ожидаемый: конкретно, со ссылкой на ТЗ или макет
Фактический: что произошло
Severity: Blocker / Critical / Major (есть обход) / Minor / Trivial — техническая оценка, ставит QA
Priority: High / Medium / Low — срочность для бизнеса (решает PO/PM)
Воспроизводимость: Always (10/10) или Intermittent (например, 1/10)
Workaround: альтернативный путь, если есть
Вложения: скриншот для статики, видео для динамики, логи консоли или HAR для бэкенда
Правила: 1 баг = 1 тикет; перед заведением поищи дубль; заводи сразу; нейтральный тон; не выдумывай фикс в тикете; пиши так, чтобы через месяц по описанию можно было проверить исправление. Severity и Priority независимы (опечатка в логотипе: Trivial / Immediate).
Отчёт о тестировании (TRR)
Минимум воды, максимум цифр и явная рекомендация Go / No-Go:
ОТЧЁТ О ТЕСТИРОВАНИИ СБОРКИ vX.Y
Запланировано N кейсов: Passed a (a%) · Failed b (b%) · Blocked c (c%)
Дефекты: BUG-… — суть (приоритет) [ссылка] …
Заблокировано: какой блок и из-за каких багов
Рекомендация QA: выпуск НЕ рекомендован / рекомендован с условиями …
Шаг 5. UI: формы, GUI, удобство, доступность, совместимость, локализация
Формы и поля ввода
- Текст: валидное значение; пустое обязательное поле; ровно max; max+1; спецсимволы
' " < > / ; : @ # $ % ^ & * ( ) _ +; эмодзи (падение на utf8mb4); только пробелы, ведущие, хвостовые и внутренние пробелы (ожидается trim); смешение кириллицы, латиницы, иероглифов и RTL; F5 сохраняет ввод (кроме пароля и капчи); двойной клик «Отправить» не шлёт два запроса; U+200B. - Пароль: маскирование; очищается при перезагрузке и ошибке; проверка на слабый пароль и на совпадение с логином или email; вставка из буфера и менеджера паролей; «глазик» переключает password ↔ text.
- Выбор и загрузка: разумные значения по умолчанию (согласие не отмечено заранее — GDPR); клик по лейблу
переключает чекбокс; «выбрать все / снять все»; обязательная группа радиокнопок; запрещённые расширения
(
.exe,.php), файл 0 байт и 100 МБ+, прогресс-бар. - UX валидации: inline-проверка на blur, введённое не сбрасывается при ошибке, поле подсвечено и рядом причина с CTA; формат подсказан заранее («ДД.ММ.ГГГГ»); одно поле — одно значение; экран успеха с номером, статусом и следующим шагом; «Назад» в многошаговой форме сохраняет данные или явно запрещён.
- Плюс БЛУГИД: Tab / Shift+Tab / Enter, Safari и мобайл, переводы ошибок, XSS, SQL, CSRF, rate limit.
GUI: сверка с макетом (Figma + DevTools)
Начинай с Common Components — фикс в общем компоненте чинит десятки экранов. Размеры — расширение Pixel
Measurement (ширина «меньше макета» при открытом DevTools — адаптив, а не баг). Шрифты и цвета —
Elements → Computed (font-size, background-color → HEX). Отступы — Option/Alt в Figma против Box Model.
Анимации — Command Palette → Show Animations, замедлить до 10–25%. Наложение — PerfectPixel при 50% opacity.
Разница в 1 px — не баг (субпиксельное округление), если вёрстка не поплыла.
Удобство (usability)
Проверяй по 10 эвристикам Нильсена: статус системы, язык пользователя, контроль и Undo, стандарты платформы (HIG / Material), предотвращение ошибок, узнавание вместо запоминания, ускорители, минимализм, понятные ошибки, справка. Для взрослой аудитории: шрифт не мельче 12 pt, контраст, крупные цели. Не ломай нативные паттерны: двойной тап, системные жесты у края экрана. Отмена с «Undo» на 5 секунд лучше диалога «Вы уверены?».
Доступность (WCAG, POUR)
Быстрый прогон: Lighthouse (только Accessibility) → axe DevTools → IBM Equal Access → ANDI (порядок Tab
и имена элементов) → контраст (AA ≥ 4.5:1, AAA ≥ 7:1). Текст поверх картинки или градиента перепроверяй
пипеткой DevTools: сканеры берут цвет соседнего тега. Руками: вся работа без мыши, видимый и не перекрытый
фокус, alt у информативных картинок, ничего не мигает чаще 3 раз в секунду, уважается prefers-reduced-motion,
скринридер (NVDA / VoiceOver). Симуляции — Web Disability Simulator.
Совместимость
Матрицу строй по данным: своя аналитика → региональная статистика → StatCounter (и сообщи о риске недопокрытия). Смотри на выручку по платформам, а не только на трафик. Отбрось хвост < 0,5%. Группируй по движку: Chrome и Edge на Windows — один Chromium; все браузеры на iOS — WebKit, но Safari на iOS тестируй отдельно (свои баги вёрстки). Распредели регресс пропорционально долям (200 кейсов × доля группы), а не pairwise «браузер × кейс» (это 1400 прогонов). Нехватку устройств закрывают облачные фермы (BrowserStack) и эмуляторы.
Локализация
Форматы дат (ДД.ММ.ГГГГ / ММ/ДД/ГГГГ / ГГГГ/ММ/ДД), первый день недели, 12- и 24-часовой формат, нелокальные календари; положение символа валюты, отрицательные суммы, разделители (1 025,70 ₽ / $1,025.70 / индийские лахи 12,34,56,789); порядок адреса, отсутствие индекса, длина и формат телефонов; разбухание текста (немецкие составные слова), высота строк (тайский), RTL с полным зеркалированием; пробелы перед знаками во французском, ¿¡ в испанском, склонение имён; глифы шрифта для всех языков; цвета, жесты, числа (4, 13) и политически чувствительные сочетания; юридическая адаптация. Длинные тексты удобно подставлять моком ответа (шаг 6).
Клиентская производительность
DevTools → FPS meter; Performance → запись 5–10 с → красные и жёлтые кадры (из 60 кадров в секунду минус потерянные = реальный FPS). Слабое железо — CPU throttling 4x / 6x. Утечки памяти: Performance с галкой Memory, 10–20 циклов «открыть → закрыть»; JS Heap «пилой» — норма, «лестницей вверх» — утечка. Где искать: карточки и профили (30 открытий подряд), бесконечная лента (500 постов), виджеты с polling или WebSocket (вкладка открыта полчаса).
Шаг 6. API
Что смотреть в DevTools → Network
Фильтр Fetch/XHR, включены Preserve log и Disable cache. Headers — URL, метод, статус, токен, Content-Type; Payload — что ушло; Response / Preview — что пришло; Timing — где время. По статусу локализуй виновника: 4xx — запрос или клиент, 500 — исключение на бэкенде, 502 / 504 — шлюз и таймаут, «кнопка не работает» без запроса — фронт.
Опорные статусы: 200, 201 (создано), 202 (асинхронно), 204 (DELETE без тела), 304; 400 (синтаксис), 401
(не аутентифицирован), 403 (нет прав), 404, 405 (метод), 409 (конфликт), 413, 415, 422 (семантическая
валидация), 429 (rate limit); 500, 502, 503, 504. 200 с ошибкой в теле — антипаттерн псевдо-REST,
заводи как риск. Исключение — GraphQL: там 200 и массив errors — норма. Идемпотентны GET, PUT, DELETE;
POST — нет (повтор создаёт дубль).
BINMEN — негатив по структуре и типам
| Что делать | Ожидание | |
|---|---|---|
| Boundary | длина max+1, лимиты | 422 + поле + единица измерения в тексте |
| Invalid | строка вместо числа ("roomid": "one") | понятная ошибка типа |
| Negative | отрицательные или несуществующие ID и даты | «Room -1 does not exist», не 500 |
| Method | DELETE / PUT вместо POST | 405 с телом и списком методов |
| Empty | "" в обязательных полях | 4xx с понятным текстом |
| Null | null и удаление ключа — по каждому полю отдельно | 4xx; 500 = нет null-проверки |
POISED — бизнес-логика
- Parameters: порядок ключей (не баг по RFC 8259); логика дат (выезд раньше заезда); приведение типов
"false"(закон Постела — зафиксируй решение команды);Accept: application/xml→ XML или 406. - Output: статус по спеке, заголовки, нужные поля (id созданного объекта), время ответа.
- Interoperability: сквозной CRUD через смежные эндпоинты; после удаления ресурс снова свободен.
- Security: каждый эндпоинт без токена → 401 (списки забывают чаще, чем
/:id); подделка клиентских флагов ("depositpaid": true); чужие объекты (403); SQL в строках; лишние служебные поля в ответе; брутфорс → 429. - Errors: ошибка называет поле и причину, код правильный (422, а не общий 400).
- Data: проверь в БД или повторным GET, что сохранилось без округлений и битой кодировки (100.50 ≠ 101).
Проверяй только статусы, заложенные в спеку (Swagger / OpenAPI), а не все 50 кодов RFC.
Безопасность API — OWASP API Security Top 10 (2023) [вне книги]
Автор безопасность сознательно не разбирает. Список OWASP — не чек-лист, а источник тест-идей; для QA он превращается в проверки, которые делаются тем же Postman с двумя аккаунтами (A и B) и разными ролями:
| Риск | Что проверить |
|---|---|
| API1 Broken Object Level Authorization (BOLA) | под пользователем A запросить объект B по ID (GET /orders/{id_B}), перебрать соседние ID; ждём 403/404, а не чужие данные |
| API2 Broken Authentication | вход без токена, с протухшим, с чужим, с изменённым JWT; брутфорс логина → блокировка или 429 |
| API3 Broken Object Property Level Authorization | в ответе нет лишних полей (хэши, is_admin, чужие email); в PATCH нельзя записать служебное поле ("role": "admin", "balance") |
| API4 Unrestricted Resource Consumption | огромный limit/page_size, файл сверх лимита, сотни запросов подряд → 413 / 429, а не падение |
| API5 Broken Function Level Authorization | обычный пользователь вызывает админские методы (DELETE /users/{id}, /admin/*) → 403 |
| API6 Unrestricted Access to Sensitive Business Flows | скриптом повторить бизнес-процесс: массовые регистрации, бонусы, брони, скупка последних товаров |
| API7 SSRF | параметры с URL (аватар по ссылке, вебхук) не дают сходить на localhost, внутренние адреса и метаданные облака |
| API8 Security Misconfiguration | стек-трейсы и версии в ошибках, открытые debug-эндпоинты, CORS * с куками, HTTP без HTTPS |
| API9 Improper Inventory Management | живы ли старые версии (/v1/), тестовые и забытые эндпоинты, не описанные в Swagger |
| API10 Unsafe Consumption of APIs | как система ведёт себя, если сторонний API вернул мусор, 500 или таймаут (мок через Proxyman) |
Находки безопасности — Severity не ниже Critical; публично в общий чат не выкладывать.
Контрактное тестирование [вне книги]
Для систем из нескольких сервисов: потребитель (фронт или другой сервис) описывает, какие поля и форматы ему нужны, провайдер в своём CI проверяет, что этот контракт выполняется (Pact; упрощённо — валидация ответа по схеме OpenAPI). Ловит «бэкенд переименовал поле, фронт сломался» в пул-реквесте, а не на стенде. E2E не заменяет — закрывает стыки раньше и дешевле.
Инструменты и приёмы
- Swagger — справочник: эндпоинты, required, типы, коды. Тестировать — в Postman (Copy as cURL → Import).
- Postman: окружения (
{{baseUrl}}, токены, логины ролей, ID для цепочек, фича-флаги); Post-responsepm.environment.set("token", pm.response.json().token);; Pre-request подставляет токен в заголовок. - Application: снести куку сессии → редирект на логин и отказ бэка; Expires через минуту → повторный логин; очистка Local Storage → корзина 0, тема по умолчанию, онбординг снова показан, черновик сброшен; гостевая корзина сливается с корзиной аккаунта при логине; чистый пользователь для A/B; отзыв прав на камеру или гео в Site Settings на лету — без Uncaught TypeError.
- Моки (Local Overrides, Proxyman / Charles): подменить ответ на
[](empty state), на текст в 150 символов (переполнение, ellipsis), на 500 / 403 / 404 (обработка ошибок); Network request blocking отдельных запросов (страница деградирует частично, а не падает целиком); тест фронта до готовности бэка.
Нагрузка (k6)
Метрики: error rate, response time (p90 / p95, не только среднее), VUs, RPS, пиковая пропускная способность.
Профили: smoke (2–5 VU, 1–2 мин) → average (плато нормы 10–60 мин) → stress (×3–4 нормы) → spike
(0→1000 за секунды) → breakpoint (рост до отказа, threshold http_req_failed: ['rate>0.0']) → soak
(12–72 ч, утечки). Авторизация один раз в setup(). Параллельно смотри Grafana: CPU, RAM, пул соединений БД.
Шаг 7. Мобильные приложения (кратко)
Тип приложения определяет объём: нативные — тестировать iOS и Android параллельно (разный код); гибриды —
сеть; мобильный веб — Safari и нет нативного железа.
Обязательный набор: прерывания (звонок, пуш, будильник, зарядка, наушники, скриншот, 20% и 5% батареи,
энергосбережение); установка, обновление (сессия и локальная БД сохраняются), переустановка, удаление;
сеть (Wi-Fi ↔ 4G на лету, слабый сигнал, потеря пакетов, обрыв во время POST); CPU, RAM, батарея; поворот
экрана во время загрузки; жесты; оболочки (Samsung, Xiaomi, Huawei без GMS); 2–3 версии iOS и 5–6 Android
плюс беты новых ОС; разрешения: дал / отказал / отозвал в настройках (проверять при каждом вызове).
Lifecycle: сворачивание во время долгой операции, возврат из фона без белого экрана, process death.
ADB: adb install app.apk, adb shell pm clear <pkg>, adb logcat "*:E", adb logcat -d > crash_log.txt,
adb shell dumpsys battery set level 5 / reset, adb shell screenrecord /sdcard/v.mp4.
Process death [вне книги: команда]: свернуть приложение → adb shell am kill <pkg> → вернуться
через Recent Apps — состояние и ввод должны восстановиться.
Шаг 8. Автоматизация
Пирамида: unit (разработчики, тысячи за секунды) → API / интеграционные (сердце логики) → немного E2E → ручной слой сверху (исследовательское, новые фичи). Для микросервисов — «соты» (упор на интеграционные), для фронта — «трофей» (статический анализ + интеграционные). Антипаттерны: «рожок мороженого» (сотни хрупких E2E, которым никто не верит) и пирамида без API-слоя.
Правило автора: автоматизацию начинать с API — такие тесты пишутся в разы быстрее UI, идут секунды и падают только по делу.
Что автоматизировать в первую очередь: smoke сборки; регресс по стабильным тест-кейсам (отсюда требование атомарности и изолированности); API-контракты и BINMEN / POISED по ключевым эндпоинтам; кросс-браузерный регресс (параллельный запуск); нагрузку (k6). Руками: новые и часто меняющиеся фичи, юзабилити, исследовательское, визуальная сверка с макетом.
CI/CD: тесты на каждый пуш, по стадиям unit (1–2 мин) → API (3–5 мин) → E2E (10–20 мин); красная стадия блокирует слияние. Релизный цикл: code freeze → smoke → new feature / sanity → регресс → прод (при баге — hotfix + re-test).
UI-автотесты [вне книги, по официальному гайду Playwright]
В руководстве нет фреймворков UI-автоматизации. Правила для Playwright (для Selenium — те же принципы):
- Тестируй видимое пользователю поведение, а не устройство вёрстки. Тест не должен ломаться, если убрали CSS-класс, а для пользователя ничего не изменилось.
- Локаторы по приоритету:
getByRole('button', { name: 'Оплатить' })→getByLabel→getByText/getByPlaceholder→getByTestId→ CSS/XPath только в крайнем случае. - Web-first проверки, которые ждут сами:
await expect(locator).toBeVisible(),toHaveText,toHaveURL. Нельзяexpect(await locator.isVisible()).toBe(true)— проверит один раз и упадёт, если UI отстал на кадр. - Никаких
waitForTimeout/sleep. Ждать нужное состояние или ответ (page.waitForResponse). - Изоляция: каждый тест сам готовит свои данные (через API, не кликами), не зависит от порядка
и чистит за собой. Логин один раз в setup-проекте, дальше — сохранённый
storageState, а не вход через UI в каждом тесте. - Внешние сервисы мокать (
page.route), реальные платёжки и сторонние API в тестах не дёргать. - Page Object для повторяющихся экранов; trace, скриншот и видео — при падении; параллельный запуск по браузерам в CI.
Флейки (нестабильные тесты) [вне книги]
Цифры для аргумента «зачем пирамида»: в Google флейкали ~0,5% маленьких тестов, 1,6% средних и 14% больших; у тестов на Java WebDriver — 10,45%. Главная причина и в бэкенде, и в UI — асинхронные ожидания (около 45% случаев), дальше — общий изменяемый стейт и зависимость от порядка, время и даты, внешние сервисы, утечки ресурсов. Правила:
- красный тест перезапускать молча нельзя — повторно прошедший тест может прятать настоящий баг (гонку, проблему с таймаутом);
- флейк получает тикет с причиной; не чинится сразу — в карантин (отдельная метка, не блокирует сборку, но виден в отчёте), с владельцем и сроком;
- считать флейк-рейт: прогнать набор 10 раз без изменений кода и посмотреть, какие тесты падали;
- проверять свойства, а не случайные значения (ID — валидный UUID, время — в окне, а не равно конкретному).
Шаг 9. Тестирование функций на LLM [вне книги]
Если в продукте есть чат-бот, генерация текста, ИИ-поиск или суммаризация: одинаковый запрос даёт разные ответы, поэтому сравнение со строкой и снапшоты гарантированно флейкают. Меняется оракул, а не подход:
- Детерминированный слой — максимум проверок здесь. Обвязка вокруг модели: API принимает и отдаёт нужный формат, ответ валидный JSON по схеме, длина в лимитах, таймаут и ошибка модели обработаны, UI корректно показывает длинный, пустой и разметочный ответ, логи пишутся. Модель в этих тестах мокается.
- Свойства ответа (rule-based): нет персональных данных, есть ссылка на источник, язык ответа = язык вопроса, нет запрещённых тем, цифры и названия есть в переданном контексте (не выдуманы).
- Границы — что модель не должна делать никогда: раскрывать системный промпт, выполнять инструкции из пользовательского ввода и документов (prompt injection), выдумывать несуществующие заказы, цены, ссылки, отвечать вне своей области. Эти проверки тоже pass/fail.
- Качество — баллами по рубрике, а не pass/fail. Набор из 25–30 эталонных вопросов по ключевым сценариям; оценка человеком или «LLM-судьёй» с жёсткой шкалой (например 1–5 по полноте, точности, тону); смотрим тренд между версиями промпта и модели, а не один прогон.
- Обратная связь: каждый провал с прода становится новым кейсом в эталонном наборе. Прогон набора — после каждого изменения промпта и при смене версии модели.
Шаг 10. Если работаешь с ИИ-генерацией
Из руководства: ИИ ошибается в комбинаторике и границах — матрицы считай инструментом, границы проверяй по 3BVA. Сгенерированные элементы и шаги сверяй с реальным интерфейсом (галлюцинации). Длинный смешанный контекст деградирует — разные задачи вести отдельно. Полезно: объяснение git diff для QA (суть, изменения, позитив, негатив, риск регрессии), разбор расхождения «требование ↔ код ↔ факт».
Формат результата
- Чек-лист — таблица
ID | Проверка | Тип (позитив/негатив/нефункц.) | Приоритет, сгруппированная по свитам. - Тест-кейсы и баги — по шаблонам выше, на языке пользователя.
- Каждый вывод о баге опирается на увиденное (ответ, скриншот, лог), а не на догадку. Не проверено — так и пиши: «не проверено, нужен доступ к …».
- В конце — короткий TRR или список рисков и открытых вопросов к аналитику.
Источники дополнений [вне книги]
- OWASP API Security Top 10 (2023) — owasp.org/API-Security
- Playwright, Best Practices — playwright.dev/docs/best-practices
- Google Testing Blog, «Where do our flaky tests come from?» (J. Listfield); Luo et al., FSE 2014 — причины флейков
- J. Bach, Heuristic Test Strategy Model — satisfice.com; M. Bolton, FEW HICCUPPS — developsense.com
- J. & J. Bach, Session-Based Test Management — satisfice.com
- Pact — docs.pact.io
- Практики тестирования LLM-функций: многослойная оценка, LLM-as-judge, эталонный набор (обзоры QA Wolf, NashTech, Testomat.io)