does-it-work: проверка продукта и защита качества автотестами
Скилл отвечает на вопрос «а оно вообще работает?»: прогоняет живое приложение
тестами, находит баги (репорт с severity) и оставляет каркас автотестов как защиту
от регрессий. Пять эталонных каркасов в templates/ — все проверены запуском
против живых стендов. Копируйте их структуру и стиль, а не пишите с нуля.
Оформление (все ветки): имена функций/переменных — латиницей, docstrings, allure-тайтлы,
шаги и тексты assert-сообщений — на русском.
Выбор ветки
| Задача |
Стек |
Шаблон |
| API-тесты на Python (дефолт для API) |
pytest + httpx (sync) + Pydantic |
templates/api-python/ |
| API-тесты на Java |
JUnit 5 + REST Assured + Maven |
templates/api-java/ |
| UI-тесты на Python (дефолт для WEB) |
Playwright + Page Object |
templates/web-python-playwright/ |
| UI-тесты на Python (легаси/требование) |
Selenium + Page Object |
templates/web-python-selenium/ |
| UI-тесты на Java |
Selenide + JUnit 5 |
templates/web-java-selenide/ |
Если тип (API/WEB) или язык не следует из запроса и контекста проекта — задай один
вопрос пользователю до генерации. README каждого шаблона описывает паттерны своей ветки.
Java- и WEB-шаблоны — проверенные примеры на реальном приложении RV Booker: замените
ресурсы/страницы на свои, сохранив структуру слоёв.
Общие конвенции всех веток (подробно раскрыты ниже на python-ветке, остальные
зеркалят): слои клиенты/страницы → модели → тесты по фичам; конфиг только из
env-переменных (API_TESTS_* / WEB_TESTS_*); маркеры/теги smoke/critical/negative/flaky
- severity на каждом тесте; строгие контракты (Pydantic
extra="forbid" / Jackson records);
никаких sleep — только ожидания (wait_until / Awaitility / встроенные в Playwright и
Selenide); environment.properties и категории в Allure; зелёный прогон обязателен;
«Самопроверка качества» и «Red flags» (секции ниже) применяются во всех ветках.
Специфика WEB-веток: Page Object (страница = класс, локаторы — свойства/константы,
действия — методы с шагом); подготовка данных и логин — через API в обход UI
(форма логина — отдельный тест); артефакты при падении (скриншот + HTML) в Allure;
селекторы: стабильные id → роли → css, хрупкие xpath запрещены; мобильные вьюпорты
и кросс-браузерная CI-матрица — в Playwright-шаблоне.
Маршрутизация: что читать под задачу
- «Проверь мой продукт / найди баги / можно ли в прод» (аудит навайбкоженного
или незнакомого приложения) → главный деливерабл — не каркас, а вердикт.
Порядок: префлайт стенда → чек-лист аудита
(reference/prod-readiness.md: авторизация, утечки,
целостность данных, фаззинг по OpenAPI) → smoke ядра → карта покрытия →
баг-репорт с severity (examples/bug-report.md) →
вердикт go/no-go (examples/prod-readiness-report.md)
с обязательным разделом «что НЕ проверено». Чек-лист идёт раньше каркаса: типичное
вайб-кодовое приложение сыпется на первом же блоке, и полдня на Page Object'ы до
этого — не то, за чем к вам пришли. Каркас (шаги 1–5) остаётся пользователю как
защита от регрессий, покрытие начинается с мест, где нашлись Critical/High.
- Новый проект с нуля → выбор ветки (таблица выше) + весь порядок работы (шаги 1–5);
детали api-python (структура, паттерны с кодом, режимы запуска, gotchas) —
reference/api-python.md, детали остальных веток —
README их шаблонов.
- Дописать тесты в существующий проект → шаг 1 (режим «существующий»), шаги 2, 4, 5.
- Стабилизировать флакающие тесты →
reference/stabilize-and-review.md, режим
«Стабилизация»: воспроизведи повторами (
scripts/flake_hunt.sh -n 10 -- <команда>)
→ классифицируй причину → почини причину, не симптом → докажи N зелёными прогонами
подряд (--prove). Каркас не разворачивай.
- Ревью существующих тестов → там же, режим «Ревью»: сначала запуск, потом
чек-листы (включая шаг 5 ниже), находки с severity, отчёт до правок.
- Только негативные кейсы / контракты → шаг 2 + паттерны «негативные», «контракт»
из шага 3; каркас не разворачивай.
- API с логином/ролями или общий стенд → плюс
reference/live-api-patterns.md.
- WEB-тесты → README выбранного web-шаблона; разведай DOM живого приложения
(Playwright-скриптом) до написания Page Object'ов — не выдумывай селекторы.
- Источник — не OpenAPI (код, требования, curl/HAR) →
reference/input-sources.md.
- Стенд недоступен/сомнителен → сначала
scripts/check_env.py (см. шаг 2).
Порядок работы (общий для всех веток; детали ветки — по ссылкам в шагах)
1. Определи режим
- Новый проект → разверни каркас из шаблона выбранной ветки, подставь реальные
эндпоинты/страницы вместо примера.
- Существующий тестовый проект → сначала изучи его: conftest, базовый клиент, стиль
именования, маркеры. Новые тесты пиши в стиле проекта; паттерны из
templates/
применяй только там, где в проекте нет своего решения. Не дублируй существующие фикстуры.
2. Извлеки тест-кейсы из источника
Источником может быть OpenAPI-спека, исходный код сервиса, текстовые требования или
примеры запросов (curl/Postman/HAR). Рецепты по каждому — в
reference/input-sources.md. Если источник неоднозначен —
задай вопросы пользователю до генерации, не додумывай.
Перед генерацией проверь стенд префлайт-скриптом — он покажет доступность,
латентность и работоспособность авторизации до того, как ты напишешь хоть один тест.
Скрипт лежит в директории скилла, а cwd при работе — проект пользователя, поэтому
вызывай его по полному пути к директории скилла:
python <директория-скилла>/scripts/check_env.py https://stage.example.com/api [--token ...]
Если в API больше ~15 операций — не генерируй вслепую: построй карту покрытия
(таблица «метод + путь → планируемые тесты»), согласуй с пользователем объём
(полное покрытие / ядро / конкретные фичи, образец —
examples/coverage-map.md) и сохрани карту в docs/coverage.md
сгенерированного проекта. По ней видно, что покрыто, а что осознанно отложено;
обновляй её при доработках.
3. Сгенерируй код по слоям
Полная структура каркаса, код паттернов и разбор каждого пункта —
reference/api-python.md (эталон — templates/api-python/;
остальные ветки зеркалят её, синтаксис — в README своего шаблона). Коротко:
config.py clients/ models/ utils/ tests/<feature>/ pytest.ini .env.example README.md
Принципы, обязательные во всех ветках:
- Тесты не ходят в HTTP/DOM напрямую — только через клиентов и Page Object'ы.
- Проверки — через утилиты (
assert_status / assert_contract / assert_error),
а не голыми assert: Allure-шаг и читаемое сообщение бесплатно.
- Контракт ответа проверяется моделью с
extra="forbid" — включая тела ошибок.
- Никаких sleep — только ожидания (
wait_until, Awaitility, встроенные ожидания
Playwright и Selenide). Асинхронный ответ (202/processing) — отдельный тест
с поллингом до конечного статуса.
- Каждому happy path — негативные в пару: невалидное тело (422), без авторизации
(401), не существует (404); негативные — одним параметризованным тестом
с человекочитаемым
case_id.
- Данные — фабрики (faker), очистка — в teardown, teardown не падает на уже
удалённом ресурсе. Хардкодов id/email/дат нет.
- Таксономия разметки: маркеры/теги
smoke, critical, negative, flaky
(карантин, CI гоняет -m "not flaky") + @allure.severity на каждом тесте
(blocker — ключевые happy path, critical — авторизация, normal — остальное,
minor — 404 и косметика). В web- и java-ветках дополнительно тег e2e.
- Группировка по фиче, не по типу теста: директория = фича, файл = сценарная
группа, ≤1 класса на файл. Allure-иерархия: feature = директория, story = файл.
- README.md обязателен во всех ветках,
.env.example — в python-ветках
(в java вместо него таблица env-переменных в README).
- Живой стенд и динамическая авторизация (register/login, роли, общие данные) —
паттерны из reference/live-api-patterns.md,
там же Java-эквиваленты.
4. Запусти и добейся зелёного прогона — обязательно
Сгенерированные, но не запущенные тесты — не результат. Разворачивание окружения —
скриптами из директории скилла (запускать из корня сгенерированного проекта,
путь к скрипту — полный): python-ветки — scripts/bootstrap.sh (venv +
зависимости + проверка коллекции), java-ветки — scripts/bootstrap-java.sh.
Режимы запуска, Allure-артефакты и заглушка API на случай «стенда нет вообще» —
reference/api-python.md.
Если тест падает из-за реального расхождения API со спекой — не подгоняй тест
под фактическое поведение молча: покажи расхождение пользователю. Подтверждённый
баг фиксируй тестом с xfail(reason="Баг API: ...", strict=True) — прогон остаётся
зелёным, а когда баг починят, тест сам просигналит (XPASS→FAILED).
Найденные баги классифицируй по severity (шаблон —
examples/bug-report.md): Critical — потеря денег/данных,
дыры авторизации; High — функция не работает или спека врёт о ключевом поведении;
Medium — принимаются невалидные данные, неверные коды ошибок; Low —
расхождения форматов, косметика.
5. Самопроверка качества — после зелёного прогона
Зелёный ≠ качественный. Сначала прогони линтер — он проверяет механическую часть
чек-листа детерминированно (python- и java-ветки):
python <директория-скилла>/scripts/review_tests.py . # порог падения — high
python <директория-скилла>/scripts/review_tests.py . --json # машиночитаемо
Находит: тесты без единой проверки, проверки только статус-кода, sleep, секреты
и URL в коде, хрупкие xpath, extra="ignore", xfail без strict, отсутствие
severity, карантин без комментария, пропущенные __init__.py. Эталонные шаблоны
проходят его без единой находки — сгенерированный код обязан тоже.
Ноль находок линтера — не отмазка от чтения кода: дальше глазами по чек-листу,
каждое «да» — чинить:
- Есть тест, который проверяет только статус-код, хотя ответ содержит тело?
(слабый assert — добавь контракт/проверку полей)
- Есть проверки только «поле существует», где можно проверить значение?
- Тест зависит от результатов другого теста или от порядка запуска?
- В данных есть хардкоды (id, email, даты), которые сломаются на другом стенде?
- Название теста содержит «и» — он проверяет два поведения? Раздели.
- Негативный кейс проверяет только код ошибки, но не контракт тела ошибки?
- Happy path без пары негативных (401/404/невалидное тело)?
- Есть
time.sleep вместо wait_until?
- Асинхронные операции API (202/processing) проверены до конечного статуса?
- Все тесты размечены маркерами и severity?
Red flags — сигналы остановиться
Если ловишь себя на одной из этих мыслей — остановись, это ошибка процесса:
| Мысль |
Реальность |
«Ослаблю модель (extra="ignore", Any), чтобы прошло» |
Это расхождение контракта — покажи пользователю, ослабляй только точечно с комментарием |
| «Поменяю ожидаемый статус на фактический, спека наверное устарела» |
Может и устарела — но это решает пользователь, а не тест |
| «Тест против живого API прошёл с первого раза — отлично» |
Проверь, что он вообще может упасть: сломай ожидание и убедись, что падает |
| «Этот эндпоинт слишком простой, чтобы тестировать» |
Простые эндпоинты ломаются так же часто; health-check — самый дешёвый smoke |
| «Пропущу запуск, тесты очевидно корректные» |
Незапущенные тесты — не результат (шаг 4 обязателен) |
| «Данные захардкожу, на этом стенде они всегда есть» |
Стенд общий/пересоздаваемый — бери опорные данные запросом, генерируй свои фабрикой |
| «Флаки-тест перезапущу, наверное повезёт» |
Разберись в причине; временно — маркер flaky (карантин), не игнор |
Режимы запуска и CI
- Переключение окружений — только через env-переменные
API_TESTS_* (см. config.py),
без правок кода. Приоритет: переменная окружения → .env → дефолт в config.py.
Зафиксированное решение пользователя: не добавлять CLI-флаги (--base-url через
pytest_addoption) и плагины (pytest-base-url) — один источник правды Settings,
ноль лишних зависимостей; вместо этого механизм документируется в README
(примеры терминала + CI-матрица, шаблон в templates/api-python/README.md).
- Для CI:
pytest -m "not flaky" (карантин не валит регрессию; флаки гоняются
отдельной джобой -m flaky), --alluredir уже включён; среда задаётся переменными
джобы (матрица сред), секреты — только через env, не через флаги (флаги видны в логах CI).
- Готовый workflow в
templates/api-python/.github/workflows/api-tests.yml — две джобы:
прогон + публикация Allure-отчёта на GitHub Pages с переносом history/
(тренды между прогонами копятся автоматически).
- Jenkins: в каждом шаблоне лежит
Jenkinsfile (declarative pipeline) —
параметры стенда и объёма прогона, секреты через credentials(), публикация
Allure шагом allure. Падение тестов помечает сборку UNSTABLE, а не FAILURE:
иначе отчёт не соберётся именно тогда, когда он нужнее всего. Тренды и история
в Jenkins работают из коробки — плагин сам переносит history между сборками,
копировать вручную (как для Pages) не нужно. Требуемые плагины и имена установок
инструментов — в шапке каждого Jenkinsfile.
Чего скилл не делает
Говорите об этом прямо и заранее, а в аудите — отдельным разделом отчёта:
нагрузочное и стресс-тестирование; пентест (SQLi/XSS/SSRF-эксплуатация, инфраструктура,
зависимости); аудит исходного кода как таковой; мобильные приложения (Appium);
визуальные регрессии (скриншотное сравнение); тестирование на соответствие
(152-ФЗ, GDPR). Непроверенное, выданное за проверенное, вреднее ненайденного бага.
Gotchas
Грабли, найденные реальными прогонами, — в ветке, где они водятся:
api-python — reference/api-python.md, остальные ветки —
раздел «Gotchas» в README своего шаблона. Прочитай их до генерации кода:
половина из них ломает прогон ещё на коллекции тестов.
1---2name: does-it-work3description: Проверка, что продукт реально работает, и защита его качества автотестами. Аудит работающего (в т.ч. навайбкоженного) приложения: найти баги, оценить готовность к проду, выдать баг-репорт с severity. Генерация тестовых фреймворков: API-тесты на Python (pytest + httpx + Pydantic + Allure) и Java (JUnit 5 + REST Assured), WEB/UI-тесты (Playwright, Selenium, Selenide, Page Object); конвертация OpenAPI/Postman/curl/HAR в тесты, негативные кейсы, контракты. Также стабилизация флакающих тестов и ревью качества тестов. Triggers: "проверь мой продукт/приложение", "найди баги", "навайбкодил", "можно ли в прод", "работает ли оно", "vibe code", "напиши автотесты", "сгенерируй тесты", "покрой тестами", "e2e тесты", "UI-тесты", "Playwright", "REST Assured", "generate tests", "стабилизируй тесты", "flaky", "тесты флакают", "ревью тестов", "проверь качество тестов".4---56# does-it-work: проверка продукта и защита качества автотестами78Скилл отвечает на вопрос «а оно вообще работает?»: прогоняет живое приложение9тестами, находит баги (репорт с severity) и оставляет каркас автотестов как защиту10от регрессий. Пять эталонных каркасов в `templates/` — все **проверены запуском**11против живых стендов. Копируйте их структуру и стиль, а не пишите с нуля.1213Оформление (все ветки): имена функций/переменных — латиницей, docstrings, allure-тайтлы,14шаги и тексты assert-сообщений — **на русском**.1516## Выбор ветки1718| Задача | Стек | Шаблон |19|---|---|---|20| API-тесты на Python (дефолт для API) | pytest + httpx (sync) + Pydantic | `templates/api-python/` |21| API-тесты на Java | JUnit 5 + REST Assured + Maven | `templates/api-java/` |22| UI-тесты на Python (дефолт для WEB) | Playwright + Page Object | `templates/web-python-playwright/` |23| UI-тесты на Python (легаси/требование) | Selenium + Page Object | `templates/web-python-selenium/` |24| UI-тесты на Java | Selenide + JUnit 5 | `templates/web-java-selenide/` |2526Если тип (API/WEB) или язык не следует из запроса и контекста проекта — задай один27вопрос пользователю до генерации. README каждого шаблона описывает паттерны своей ветки.28Java- и WEB-шаблоны — проверенные примеры на реальном приложении RV Booker: замените29ресурсы/страницы на свои, сохранив структуру слоёв.3031**Общие конвенции всех веток** (подробно раскрыты ниже на python-ветке, остальные32зеркалят): слои клиенты/страницы → модели → тесты по фичам; конфиг только из33env-переменных (`API_TESTS_*` / `WEB_TESTS_*`); маркеры/теги smoke/critical/negative/flaky34+ severity на каждом тесте; строгие контракты (Pydantic `extra="forbid"` / Jackson records);35никаких sleep — только ожидания (`wait_until` / Awaitility / встроенные в Playwright и36Selenide); environment.properties и категории в Allure; зелёный прогон обязателен;37«Самопроверка качества» и «Red flags» (секции ниже) применяются во всех ветках.3839Специфика WEB-веток: Page Object (страница = класс, локаторы — свойства/константы,40действия — методы с шагом); подготовка данных и **логин — через API** в обход UI41(форма логина — отдельный тест); артефакты при падении (скриншот + HTML) в Allure;42селекторы: стабильные id → роли → css, хрупкие xpath запрещены; мобильные вьюпорты43и кросс-браузерная CI-матрица — в Playwright-шаблоне.4445## Маршрутизация: что читать под задачу4647- **«Проверь мой продукт / найди баги / можно ли в прод»** (аудит навайбкоженного48 или незнакомого приложения) → главный деливерабл — не каркас, а вердикт.49 Порядок: префлайт стенда → **чек-лист аудита**50 ([reference/prod-readiness.md](reference/prod-readiness.md): авторизация, утечки,51 целостность данных, фаззинг по OpenAPI) → smoke ядра → карта покрытия →52 **баг-репорт с severity** ([examples/bug-report.md](examples/bug-report.md)) →53 **вердикт go/no-go** ([examples/prod-readiness-report.md](examples/prod-readiness-report.md))54 с обязательным разделом «что НЕ проверено». Чек-лист идёт раньше каркаса: типичное55 вайб-кодовое приложение сыпется на первом же блоке, и полдня на Page Object'ы до56 этого — не то, за чем к вам пришли. Каркас (шаги 1–5) остаётся пользователю как57 защита от регрессий, покрытие начинается с мест, где нашлись Critical/High.58- **Новый проект с нуля** → выбор ветки (таблица выше) + весь порядок работы (шаги 1–5);59 детали api-python (структура, паттерны с кодом, режимы запуска, gotchas) —60 [reference/api-python.md](reference/api-python.md), детали остальных веток —61 README их шаблонов.62- **Дописать тесты в существующий проект** → шаг 1 (режим «существующий»), шаги 2, 4, 5.63- **Стабилизировать флакающие тесты** →64 [reference/stabilize-and-review.md](reference/stabilize-and-review.md), режим65 «Стабилизация»: воспроизведи повторами (`scripts/flake_hunt.sh -n 10 -- <команда>`)66 → классифицируй причину → почини причину, не симптом → докажи N зелёными прогонами67 подряд (`--prove`). Каркас не разворачивай.68- **Ревью существующих тестов** → там же, режим «Ревью»: сначала запуск, потом69 чек-листы (включая шаг 5 ниже), находки с severity, отчёт до правок.70- **Только негативные кейсы / контракты** → шаг 2 + паттерны «негативные», «контракт»71 из шага 3; каркас не разворачивай.72- **API с логином/ролями или общий стенд** → плюс73 [reference/live-api-patterns.md](reference/live-api-patterns.md).74- **WEB-тесты** → README выбранного web-шаблона; разведай DOM живого приложения75 (Playwright-скриптом) до написания Page Object'ов — не выдумывай селекторы.76- **Источник — не OpenAPI** (код, требования, curl/HAR) →77 [reference/input-sources.md](reference/input-sources.md).78- **Стенд недоступен/сомнителен** → сначала `scripts/check_env.py` (см. шаг 2).7980## Порядок работы (общий для всех веток; детали ветки — по ссылкам в шагах)8182### 1. Определи режим8384- **Новый проект** → разверни каркас из шаблона выбранной ветки, подставь реальные85 эндпоинты/страницы вместо примера.86- **Существующий тестовый проект** → сначала изучи его: conftest, базовый клиент, стиль87 именования, маркеры. Новые тесты пиши в стиле проекта; паттерны из `templates/`88 применяй только там, где в проекте нет своего решения. Не дублируй существующие фикстуры.8990### 2. Извлеки тест-кейсы из источника9192Источником может быть OpenAPI-спека, исходный код сервиса, текстовые требования или93примеры запросов (curl/Postman/HAR). Рецепты по каждому — в94[reference/input-sources.md](reference/input-sources.md). Если источник неоднозначен —95задай вопросы пользователю до генерации, не додумывай.9697Перед генерацией проверь стенд префлайт-скриптом — он покажет доступность,98латентность и работоспособность авторизации до того, как ты напишешь хоть один тест.99Скрипт лежит в директории скилла, а cwd при работе — проект пользователя, поэтому100вызывай его по полному пути к директории скилла:101102```bash103python <директория-скилла>/scripts/check_env.py https://stage.example.com/api [--token ...]104```105106Если в API больше ~15 операций — не генерируй вслепую: построй **карту покрытия**107(таблица «метод + путь → планируемые тесты»), согласуй с пользователем объём108(полное покрытие / ядро / конкретные фичи, образец —109[examples/coverage-map.md](examples/coverage-map.md)) и сохрани карту в `docs/coverage.md`110сгенерированного проекта. По ней видно, что покрыто, а что осознанно отложено;111обновляй её при доработках.112113### 3. Сгенерируй код по слоям114115Полная структура каркаса, код паттернов и разбор каждого пункта —116[reference/api-python.md](reference/api-python.md) (эталон — `templates/api-python/`;117остальные ветки зеркалят её, синтаксис — в README своего шаблона). Коротко:118119```120config.py clients/ models/ utils/ tests/<feature>/ pytest.ini .env.example README.md121```122123Принципы, обязательные во всех ветках:124125- **Тесты не ходят в HTTP/DOM напрямую** — только через клиентов и Page Object'ы.126- **Проверки — через утилиты** (`assert_status` / `assert_contract` / `assert_error`),127 а не голыми assert: Allure-шаг и читаемое сообщение бесплатно.128- **Контракт ответа проверяется моделью** с `extra="forbid"` — включая тела ошибок.129- **Никаких sleep** — только ожидания (`wait_until`, Awaitility, встроенные ожидания130 Playwright и Selenide). Асинхронный ответ (202/processing) — отдельный тест131 с поллингом до конечного статуса.132- **Каждому happy path — негативные в пару**: невалидное тело (422), без авторизации133 (401), не существует (404); негативные — одним параметризованным тестом134 с человекочитаемым `case_id`.135- **Данные — фабрики** (faker), очистка — в teardown, teardown не падает на уже136 удалённом ресурсе. Хардкодов id/email/дат нет.137- **Таксономия разметки**: маркеры/теги `smoke`, `critical`, `negative`, `flaky`138 (карантин, CI гоняет `-m "not flaky"`) + `@allure.severity` на каждом тесте139 (blocker — ключевые happy path, critical — авторизация, normal — остальное,140 minor — 404 и косметика). В web- и java-ветках дополнительно тег `e2e`.141- **Группировка по фиче, не по типу теста**: директория = фича, файл = сценарная142 группа, ≤1 класса на файл. Allure-иерархия: feature = директория, story = файл.143- **README.md обязателен во всех ветках**, `.env.example` — в python-ветках144 (в java вместо него таблица env-переменных в README).145- **Живой стенд и динамическая авторизация** (register/login, роли, общие данные) —146 паттерны из [reference/live-api-patterns.md](reference/live-api-patterns.md),147 там же Java-эквиваленты.148149### 4. Запусти и добейся зелёного прогона — обязательно150151Сгенерированные, но не запущенные тесты — не результат. Разворачивание окружения —152скриптами из директории скилла (запускать из корня сгенерированного проекта,153путь к скрипту — полный): python-ветки — `scripts/bootstrap.sh` (venv +154зависимости + проверка коллекции), java-ветки — `scripts/bootstrap-java.sh`.155156Режимы запуска, Allure-артефакты и заглушка API на случай «стенда нет вообще» —157[reference/api-python.md](reference/api-python.md).158159Если тест падает из-за реального расхождения API со спекой — не подгоняй тест160под фактическое поведение молча: покажи расхождение пользователю. Подтверждённый161баг фиксируй тестом с `xfail(reason="Баг API: ...", strict=True)` — прогон остаётся162зелёным, а когда баг починят, тест сам просигналит (XPASS→FAILED).163164Найденные баги классифицируй по severity (шаблон —165[examples/bug-report.md](examples/bug-report.md)): **Critical** — потеря денег/данных,166дыры авторизации; **High** — функция не работает или спека врёт о ключевом поведении;167**Medium** — принимаются невалидные данные, неверные коды ошибок; **Low** —168расхождения форматов, косметика.169170### 5. Самопроверка качества — после зелёного прогона171172Зелёный ≠ качественный. Сначала прогони линтер — он проверяет механическую часть173чек-листа детерминированно (python- и java-ветки):174175```bash176python <директория-скилла>/scripts/review_tests.py . # порог падения — high177python <директория-скилла>/scripts/review_tests.py . --json # машиночитаемо178```179180Находит: тесты без единой проверки, проверки только статус-кода, `sleep`, секреты181и URL в коде, хрупкие xpath, `extra="ignore"`, `xfail` без `strict`, отсутствие182severity, карантин без комментария, пропущенные `__init__.py`. Эталонные шаблоны183проходят его без единой находки — сгенерированный код обязан тоже.184**Ноль находок линтера — не отмазка от чтения кода:** дальше глазами по чек-листу,185каждое «да» — чинить:186187- Есть тест, который проверяет **только статус-код**, хотя ответ содержит тело?188 (слабый assert — добавь контракт/проверку полей)189- Есть проверки только «поле существует», где можно проверить **значение**?190- Тест зависит от **результатов другого теста** или от порядка запуска?191- В данных есть **хардкоды** (id, email, даты), которые сломаются на другом стенде?192- Название теста содержит **«и»** — он проверяет два поведения? Раздели.193- Негативный кейс проверяет только код ошибки, но не **контракт тела ошибки**?194- Happy path без пары негативных (401/404/невалидное тело)?195- Есть `time.sleep` вместо `wait_until`?196- Асинхронные операции API (202/processing) проверены **до конечного статуса**?197- Все тесты размечены маркерами и severity?198199## Red flags — сигналы остановиться200201Если ловишь себя на одной из этих мыслей — остановись, это ошибка процесса:202203| Мысль | Реальность |204|---|---|205| «Ослаблю модель (`extra="ignore"`, `Any`), чтобы прошло» | Это расхождение контракта — покажи пользователю, ослабляй только точечно с комментарием |206| «Поменяю ожидаемый статус на фактический, спека наверное устарела» | Может и устарела — но это решает пользователь, а не тест |207| «Тест против живого API прошёл с первого раза — отлично» | Проверь, что он вообще может упасть: сломай ожидание и убедись, что падает |208| «Этот эндпоинт слишком простой, чтобы тестировать» | Простые эндпоинты ломаются так же часто; health-check — самый дешёвый smoke |209| «Пропущу запуск, тесты очевидно корректные» | Незапущенные тесты — не результат (шаг 4 обязателен) |210| «Данные захардкожу, на этом стенде они всегда есть» | Стенд общий/пересоздаваемый — бери опорные данные запросом, генерируй свои фабрикой |211| «Флаки-тест перезапущу, наверное повезёт» | Разберись в причине; временно — маркер `flaky` (карантин), не игнор |212213## Режимы запуска и CI214215- Переключение окружений — **только через env-переменные `API_TESTS_*`** (см. `config.py`),216 без правок кода. Приоритет: переменная окружения → `.env` → дефолт в config.py.217 Зафиксированное решение пользователя: **не добавлять** CLI-флаги (`--base-url` через218 `pytest_addoption`) и плагины (`pytest-base-url`) — один источник правды `Settings`,219 ноль лишних зависимостей; вместо этого механизм документируется в README220 (примеры терминала + CI-матрица, шаблон в `templates/api-python/README.md`).221- Для CI: `pytest -m "not flaky"` (карантин не валит регрессию; флаки гоняются222 отдельной джобой `-m flaky`), `--alluredir` уже включён; среда задаётся переменными223 джобы (матрица сред), секреты — только через env, не через флаги (флаги видны в логах CI).224- Готовый workflow в `templates/api-python/.github/workflows/api-tests.yml` — две джобы:225 прогон + публикация Allure-отчёта на GitHub Pages с переносом `history/`226 (тренды между прогонами копятся автоматически).227- **Jenkins**: в каждом шаблоне лежит `Jenkinsfile` (declarative pipeline) —228 параметры стенда и объёма прогона, секреты через `credentials()`, публикация229 Allure шагом `allure`. Падение тестов помечает сборку UNSTABLE, а не FAILURE:230 иначе отчёт не соберётся именно тогда, когда он нужнее всего. Тренды и история231 в Jenkins работают из коробки — плагин сам переносит `history` между сборками,232 копировать вручную (как для Pages) не нужно. Требуемые плагины и имена установок233 инструментов — в шапке каждого `Jenkinsfile`.234235## Чего скилл не делает236237Говорите об этом прямо и заранее, а в аудите — отдельным разделом отчёта:238нагрузочное и стресс-тестирование; пентест (SQLi/XSS/SSRF-эксплуатация, инфраструктура,239зависимости); аудит исходного кода как таковой; мобильные приложения (Appium);240визуальные регрессии (скриншотное сравнение); тестирование на соответствие241(152-ФЗ, GDPR). Непроверенное, выданное за проверенное, вреднее ненайденного бага.242243## Gotchas244245Грабли, найденные реальными прогонами, — в ветке, где они водятся:246api-python — [reference/api-python.md](reference/api-python.md), остальные ветки —247раздел «Gotchas» в README своего шаблона. **Прочитай их до генерации кода**:248половина из них ломает прогон ещё на коллекции тестов.