← Назад к вопросам

Когда нужно запускать unit-тесты?

2.0 Middle🔥 161 комментариев
#Тестирование

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI28 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

Когда запускать unit-тесты

Unit-тесты должны запускаться в нескольких точках разработки, а не только перед деплоем. Правильная стратегия тестирования значительно улучшает качество кода и скорость разработки. Давайте разберемся когда и как.

1. Локально во время разработки (watch mode)

Когда: Каждый раз когда вы пишете код

Как: Используйте watch mode, который автоматически перезапускает тесты при сохранении файла:

# pytest с автоперезагрузкой
pytest --tb=short -v --maxfail=1 --lf  # run last failed

# или через pytest-watch
pytest-watch  # автоматический перезапуск при изменении файлов

# или vitest для JavaScript
npm run test:watch

Почему это важно:

  • Немедленная обратная связь (как только вы написали код)
  • Быстрое обнаружение ошибок (пока вы в контексте)
  • TDD процесс (RED → GREEN → REFACTOR)
# Пример: вы пишете тест
def test_user_creation():
    user = User(name="Alice")
    assert user.name == "Alice"

# Затем реализуете функцию
class User:
    def __init__(self, name):
        self.name = name

# Тест проходит, вы сразу это видите

2. Перед коммитом (pre-commit hook)

Когда: Перед тем как закоммитить код в git

Как: Настроить Git hook для запуска тестов:

# .git/hooks/pre-commit
#!/bin/bash
pytest --tb=short
if [ $? -ne 0 ]; then
    echo "Tests failed. Commit aborted."
    exit 1
fi

Или используйте готовые инструменты:

# husky для Node.js
npm install husky --save-dev
npx husky install
npx husky add .husky/pre-commit "npm test"

# pre-commit для Python
pip install pre-commit
# .pre-commit-config.yaml
repos:
  - repo: https://github.com/PyCQA/pytest
    rev: 7.0.0
    hooks:
      - id: pytest

Почему это важно:

  • Предотвращает коммит сломанного кода
  • Гарантирует что каждый коммит в истории работает
  • Экономит время на будущее (не придется искать "когда сломалось")

3. На pull request (CI/CD)

Когда: При создании/обновлении pull request

Как: Настроить GitHub Actions (или другой CI):

# .github/workflows/test.yml
name: Tests
on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-python@v4
        with:
          python-version: "3.11"
      - run: pip install -r requirements.txt
      - run: pytest --cov=. --cov-report=xml
      - uses: codecov/codecov-action@v3

Почему это важно:

  • Проверка на разных окружениях (Linux, разные версии Python)
  • Автоматическое блокирование PR если тесты падают
  • Отчет о покрытии кода (code coverage)
  • Спокойствие при мёрже кода

4. Перед деплоем (staging тесты)

Когда: На staging сервере перед production

Как: Добавить smoke tests + интеграционные тесты:

# tests/integration/test_api.py
def test_api_health_check(client):
    """Проверка что API отвечает"""
    response = client.get('/api/health')
    assert response.status_code == 200

def test_user_registration_flow(client, db):
    """Полный сценарий регистрации"""
    response = client.post('/api/users', json={
        'email': 'test@example.com',
        'password': 'SecurePass123'
    })
    assert response.status_code == 201
    user = User.objects.get(email='test@example.com')
    assert user is not None

Почему это важно:

  • Финальная проверка перед production
  • Тесты в условиях близких к production
  • Миграции БД работают
  • Внешние сервисы доступны

5. После деплоя (production мониторинг)

Когда: Постоянно в production

Как: Запускать smoke tests регулярно:

# Используй инструменты как Sentry, Datadog, NewRelic
# или пиши свои checks

import schedule
import requests

def health_check():
    try:
        r = requests.get('https://api.example.com/health', timeout=5)
        assert r.status_code == 200
    except Exception as e:
        send_alert(f"Production health check failed: {e}")

schedule.every(5).minutes.do(health_check)

Почему это важно:

  • Раннее обнаружение проблем в production
  • Alerting если что-то сломалось
  • Статистика uptime

Полный workflow с примерами

# 1. Вы пишете тест (локально, watch mode)
def test_payment_processing():
    order = create_order(amount=100)
    result = process_payment(order)
    assert result.status == 'success'
    # FAIL: функция еще не написана

# 2. Вы реализуете функцию
def process_payment(order):
    # Логика обработки платежа
    return PaymentResult(status='success')
    # PASS: тест проходит

# 3. Вы коммитите
# git commit -m "feat: add payment processing"
# pre-commit hook запускает тесты — все проходят ✓

# 4. Вы создаете PR на GitHub
# GitHub Actions запускают тесты на 3 версиях Python — все проходят ✓

# 5. Код залит в main
# CD запускает дополнительные интеграционные тесты на staging ✓

# 6. Деплой в production
# Сервис мониторинга регулярно запускает smoke tests ✓

Оптимизация: быстрые vs медленные тесты

Не все тесты нужно запускать везде:

# Быстрые unit-тесты (локально, часто)
pytest tests/unit -x -v  # 1-2 секунды

# Медленные интеграционные (CI, staging)
pytest tests/integration --timeout=30  # 5-10 минут

# E2E тесты (только перед продакшеном)
pytest tests/e2e --timeout=60  # 30+ минут

Конфиг:

# pytest.ini
[pytest]
markers =
    unit: unit tests (fast)
    integration: integration tests (slow)
    e2e: end-to-end tests (very slow)

Запуск:

# Локально: только unit
pytest -m unit

# CI: unit + integration
pytest -m "unit or integration"

# Staging: все
pytest

Рекомендуемый график

ТочкаТестыВремяБлокирует
Во время разработкиUnit (watch)1-5 секНет
Pre-commit hookUnit + Lint5-10 секДа (коммит)
PR (GitHub Actions)Unit + Integration30-60 секДа (мёрж)
Staging (CD)Все + E2E5-10 минДа (деплой)
Production (监控)Smoke testsкаждые 5 минДа (alert)

Инструменты

# Python
pip install pytest pytest-watch pytest-cov pytest-timeout

# Node.js
npm install jest vitest --save-dev

# CI/CD
git clone https://github.com/actions/setup-python

# Pre-commit
pip install pre-commit husky

Антипаттерны: что НЕ делать

# ❌ ПЛОХО: не запускать тесты вообще
# просто коммитить и надеяться

# ❌ ПЛОХО: запускать тесты только перед деплоем
# когда уже слишком поздно что-то менять

# ❌ ПЛОХО: игнорировать падающие тесты
pytest -x  # останови на первой ошибке

# ✅ ХОРОШО: интегрировать тесты везде
# и чинить их немедленно

Вывод

Unit-тесты нужно запускать:

  1. Локально (непрерывно, watch mode)
  2. Перед коммитом (pre-commit hook)
  3. На PR (GitHub Actions)
  4. Перед деплоем (staging)
  5. В production (мониторинг)

Этот workflow гарантирует что вы:

  • Знаете о проблемах рано (не в production)
  • Не сломаете главную ветку
  • Может спокойно деплоить
  • Получите быструю обратную связь

Это лучшая практика в профессиональной разработке.

Когда нужно запускать unit-тесты? | PrepBro