Контрольные точки качества
Updated Jul 2026
Что такое контрольная точка качества?
Контрольная точка качества (quality gate) — это контрольный пункт в вашем пайплайне, который блокирует продвижение, если критерии не выполнены. Это автоматизированный эквивалент человека-согласующего, но быстрее, более последовательный и не забывается.
Контрольная точка, которую можно обойти, — это не контрольная точка. Настраивайте их как обязательные проверки в правилах защиты основной ветки.
Распространённые контрольные точки качества
Все тесты пройдены
Самая базовая и самая важная контрольная точка. Один упавший тест блокирует слияние или развёртывание.
# GitHub branch protection: Require status checks to pass
# Settings > Branches > Branch protection rules > Require status checks
# Select: "unit-tests", "integration-tests", "browser-tests"
Почему эта контрольная точка важна: если вы разрешаете слияние при упавших тестах, разработчики быстро усвоят, что сбои тестов можно игнорировать. Через несколько недель никто не будет доверять набору тестов, и пайплайн станет декорацией.
Порог покрытия кода
Требование, чтобы покрытие не опускалось ниже базового уровня.
# Using a coverage check action
- uses: codecov/codecov-action@v4
with:
fail_ci_if_error: true
flags: unittests
# Or enforce in the test command itself
- run: npx jest --coverage --coverageThreshold='{"global":{"branches":75,"functions":80,"lines":80}}'
Лучший подход: вместо установки абсолютного порога (например, «80% в целом»), требуйте покрытия нового кода. Унаследованная кодовая база с 60% покрытия не должна блокировать PR, добавляющие хорошо протестированные новые функции.
# Codecov configuration (codecov.yml)
coverage:
status:
patch:
default:
target: 90% # New code must be 90% covered
project:
default:
target: auto # Overall coverage must not decrease
Сканирование безопасности
Интегрируйте SAST (статическое тестирование безопасности приложений) и DAST (динамическое тестирование безопасности приложений) сканеры и настройте сбой при обнаружении уязвимостей выше порога.
# Example: Snyk security scan
- uses: snyk/actions/node@master
env:
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
with:
args: --severity-threshold=high # Fail on high/critical vulnerabilities
Уровни контрольных точек:
- Критические/высокие уязвимости: блокировать слияние. Их необходимо исправить до выпуска.
- Средние уязвимости: предупреждать, но разрешать слияние. Создать задачу для последующего исправления.
- Низкие уязвимости: только информационно. Отслеживать, но не блокировать.
Бюджеты производительности
Обеспечение стандартов производительности для предотвращения постепенной деградации.
# Lighthouse CI
- run: npx lhci autorun
env:
LHCI_BUILD_CONTEXT__CURRENT_HASH: ${{ github.sha }}
# lighthouse-ci configuration
# lighthouserc.js
module.exports = {
ci: {
assert: {
assertions: {
'categories:performance': ['error', { minScore: 0.9 }],
'categories:accessibility': ['error', { minScore: 0.95 }],
'first-contentful-paint': ['warn', { maxNumericValue: 2000 }],
'largest-contentful-paint': ['error', { maxNumericValue: 2500 }],
},
},
},
};
Другие контрольные точки производительности:
- Лимиты размера бандла: сбой, если JavaScript-бандл превышает порог
- p95 времени ответа API: сбой, если 95-й перцентиль времени ответа превышает бюджет
- Оптимизация изображений: сбой, если добавлены неоптимизированные изображения
Проверки линтинга и форматирования
Обеспечение стиля кода, чтобы ревью фокусировались на логике, а не на форматировании.
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: npm ci
- run: npm run lint # ESLint
- run: npm run format:check # Prettier --check
- run: npm run typecheck # tsc --noEmit
Зачем блокировать на форматировании: без автоматического контроля код-ревью превращаются в споры о точках с запятой и отступах. Автоматизируйте тривиальные решения, чтобы люди фокусировались на архитектуре и логике.
Настройка контрольных точек в GitHub
Правила защиты веток
- Перейдите в Settings > Branches > Branch protection rules
- Добавьте правило для
main - Включите «Require status checks to pass before merging»
- Выберите конкретные проверки, которые должны пройти (например,
unit-tests,lint,security-scan) - Включите «Require branches to be up to date before merging» (гарантирует тестирование PR на актуальной версии main)
- Включите «Require pull request reviews before merging» (человеческая контрольная точка)
Обязательные vs необязательные проверки
Не каждая проверка должна быть обязательной. Используйте обязательные проверки для контрольных точек, которые нельзя обходить, и необязательные — для информационной обратной связи.
| Проверка | Обязательная? | Обоснование |
|---|---|---|
| Unit-тесты | Да | Сломанная логика не должна попасть в main |
| Линтинг / форматирование | Да | Единообразный стиль кода — это не предмет обсуждения |
| Интеграционные тесты | Да | Проблемы API и базы данных должны быть обнаружены |
| Браузерные тесты | Да (на main) | UI-регрессии должны быть обнаружены до развёртывания |
| Покрытие (патч) | Да | Новый код должен быть протестирован |
| Покрытие (общее) | Нет | Покрытие унаследованного кода должно улучшаться со временем, а не блокировать PR |
| Сканирование безопасности | Да (высокие/критические) | Критические уязвимости не должны попадать в релиз |
| Бюджет производительности | Нет (на начальном этапе) | Начните как информационную, продвигайте до обязательной после стабилизации бюджетов |
Распространённые антипаттерны пайплайнов
| Антипаттерн | Проблема | Решение |
|---|---|---|
| Тесты запускаются только на main | Баги обнаруживаются после слияния, сложнее исправить | Запускайте тесты при каждом PR |
| Нет сбора артефактов | Для отладки сбоев нужен повторный запуск всего пайплайна | Всегда загружайте отчёты, скриншоты, логи |
| Захардкоженные секреты | Учётные данные в YAML-файлах видны в истории репозитория | Используйте хранилища секретов платформы |
| Монолитный пайплайн | Одна задача выполняет всё последовательно 40 минут | Разделите на параллельные задачи с зависимостями |
| Игнорирование нестабильных тестов | Тесты с allow_failure: true, которые никто не исследует |
Изолируйте нестабильные тесты, отслеживайте и исправляйте их |
| Нет кэширования | Каждый запуск устанавливает зависимости с нуля | Кэшируйте на основе хэша lock-файла |
| Обходимые контрольные точки | «Переопределение администратором» используется регулярно, а не исключительно | Требуйте согласования администратора для обхода; отслеживайте частоту обходов |
| Слишком много контрольных точек | Каждый PR запускает 45 минут проверок | Распределяйте контрольные точки по триггерам: быстрые при push, тщательные при PR, полные при слиянии |
Советы по конфигурации пайплайна для QA
Переменные окружения для конфигурации тестов
env:
TEST_TIMEOUT: 30000 # Per-test timeout in milliseconds
RETRY_COUNT: 2 # Retries for infrastructure flakes
HEADLESS: true # Headless browser mode
SLOW_MO: 0 # No artificial delay
WORKERS: 4 # Parallel test workers
CI: true # Signal to test framework that we are in CI
Логика повторных попыток при нестабильной инфраструктуре
Повторные попытки должны справляться с инфраструктурными сбоями (таймауты сети, задержки запуска контейнеров), а не маскировать баги тестов.
- run: npx playwright test --retries=2
timeout-minutes: 30
continue-on-error: false
Если тест постоянно требует повторных попыток, изолируйте его и исправьте корневую причину.
Уведомления
Отправляйте сообщения в Slack/Teams при сбое пайплайна, чтобы команда реагировала быстро:
notify:
needs: [unit-tests, browser-tests]
if: failure()
runs-on: ubuntu-latest
steps:
- uses: slackapi/slack-github-action@v1
with:
payload: |
{
"text": "Pipeline failed on ${{ github.ref_name }}: ${{ github.server_url }}/${{ github.repository }}/actions/runs/${{ github.run_id }}"
}
env:
SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK }}
Практическое упражнение
- Перечислите все контрольные точки качества, которые сейчас есть в вашем пайплайне. Какие-либо из перечисленных выше распространённых контрольных точек отсутствуют?
- Проверьте правила защиты веток. Все ли критические проверки отмечены как обязательные?
- Намеренно попробуйте слить PR с упавшей обязательной проверкой. Убедитесь, что это заблокировано.
- Добавьте контрольную точку покрытия, требующую покрытия нового кода не менее 80%
- Добавьте сканирование безопасности и настройте сбой при обнаружении уязвимостей высокой степени серьёзности
- Настройте уведомления о сбоях в Slack-канал вашей команды
Тема для интервью: «Я рассматриваю CI/CD-пайплайн как часть тестовой инфраструктуры, а не просто инструмент развёртывания. Я структурирую пайплайны с unit-тестами как быстрой контрольной точкой при каждом push, интеграционными тестами на PR и полными браузерными наборами перед развёртыванием — каждый этап обеспечивает прогрессивно более глубокую уверенность. Я оптимизирую с помощью кэширования зависимостей, шардирования тестов на параллельных раннерах и выборочного выполнения на основе изменённых путей. Когда цикл обратной связи PR превышает 15 минут, я рассматриваю это как баг, который нужно исправить. Я настраиваю контрольные точки качества как обязательные проверки в правилах защиты веток — все тесты проходят, покрытие нового кода не снижается, критических уязвимостей безопасности нет — чтобы пайплайн был надёжной страховочной сетью, а не просто украшением.»