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

Как правильно построить процесс QA для проекта?

2.4 Senior🔥 121 комментариев
#DevOps и инфраструктура#Архитектура и паттерны#Тестирование

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

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

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

Процесс QA: построение надёжной системы контроля качества

QA — это не только тестирование. Это цикл обеспечения качества, начинающийся с планирования и заканчивающийся мониторингом в production.

1. Пирамида тестирования

Правильное соотношение тестов:

        E2E тесты (10%)
       /              \
      /                \
     /    Integration   \
    /      тесты (20%)   \
   /                      \
  /_____ Unit тесты _____\
         (70%)

Объяснение:

  • Unit тесты (70%): Быстрые, дешёвые, тестируют отдельные функции/методы
  • Integration тесты (20%): Тестируют взаимодействие компонентов (API с БД, сервисы между собой)
  • E2E тесты (10%): Дорогие, медленные, тестируют полный пользовательский flow

Пример структуры:

# tests/unit/
# └── test_calculate_price.py
# └── test_validate_email.py
# └── test_user_repository.py

# tests/integration/
# └── test_user_api.py
# └── test_order_workflow.py
# └── test_payment_integration.py

# tests/e2e/
# └── test_user_registration_flow.py
# └── test_checkout_process.py

2. Continuous Integration (CI) pipeline

Автоматический запуск тестов при каждом commit:

# .github/workflows/tests.yml
name: Tests

on: [push, pull_request]

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
      
      - name: Set up Python
        uses: actions/setup-python@v4
        with:
          python-version: '3.11'
      
      - name: Install dependencies
        run: |
          pip install -r requirements.txt
          pip install -r requirements-dev.txt
      
      - name: Lint with ruff
        run: |
          ruff check .
          ruff format --check .
      
      - name: Type check with mypy
        run: mypy .
      
      - name: Run unit tests
        run: pytest tests/unit -v --cov=app --cov-report=xml
      
      - name: Run integration tests
        run: pytest tests/integration -v
      
      - name: Upload coverage
        uses: codecov/codecov-action@v3
        with:
          files: ./coverage.xml
      
      - name: Run E2E tests (if changed)
        if: contains(github.event.pull_request.files, 'frontend') || contains(github.event.pull_request.files, 'api')
        run: pytest tests/e2e -v

3. Стратегия покрытия кода

Минимум 80-90% покрытия для critical path:

# Проверить покрытие
pytest --cov=app --cov-report=html

# Смотреть результат
open htmlcov/index.html

Правила покрытия:

# КРИТИЧНЫЙ КОД (должен быть покрыт на 100%)
def process_payment(amount: float, card_token: str) -> bool:
    """Обработка платежа — CRITICAL!"""
    if amount <= 0:
        raise ValueError("Amount must be positive")
    # ...
    return True

# ВАЖНЫЙ КОД (80-90% покрытие)
def calculate_discount(amount: float, customer_type: str) -> float:
    """Расчёт скидки"""
    if customer_type == 'premium':
        return amount * 0.2
    elif customer_type == 'regular':
        return amount * 0.1
    return 0

# УТИЛИТЫ (70% покрытие)
def format_phone(phone: str) -> str:
    """Форматирование номера телефона"""
    return phone.replace('-', '').replace(' ', '')

4. Виды тестов в Python

Unit тест (pytest):

# tests/unit/test_calculator.py
import pytest
from app.calculator import calculate_price

def test_calculate_price_with_discount():
    result = calculate_price(100, discount=0.2)
    assert result == 80

def test_calculate_price_without_discount():
    result = calculate_price(100)
    assert result == 100

def test_calculate_price_invalid_amount():
    with pytest.raises(ValueError):
        calculate_price(-100)

Integration тест (с мокированием):

# tests/integration/test_user_service.py
import pytest
from unittest.mock import Mock, patch
from app.services.user_service import UserService
from app.repositories.user_repository import UserRepository

@pytest.fixture
def user_service():
    mock_repo = Mock(spec=UserRepository)
    return UserService(user_repository=mock_repo)

def test_create_user_sends_email(user_service):
    # Arrange
    user_service.user_repository.save = Mock()
    user_service.email_service = Mock()
    
    # Act
    user_service.create_user('john@example.com', 'John')
    
    # Assert
    user_service.user_repository.save.assert_called_once()
    user_service.email_service.send_welcome.assert_called_once()

E2E тест (Playwright):

# tests/e2e/test_registration_flow.py
import pytest
from playwright.sync_api import Page

@pytest.fixture(scope="function")
def page():
    from playwright.sync_api import sync_playwright
    with sync_playwright() as p:
        yield p.chromium.launch().new_page()

def test_user_registration_flow(page: Page):
    # Arrange
    page.goto('http://localhost:3000/register')
    
    # Act
    page.fill('[name="email"]', 'test@example.com')
    page.fill('[name="password"]', 'SecurePass123')
    page.click('button[type="submit"]')
    
    # Assert
    page.wait_for_url('http://localhost:3000/dashboard')
    assert page.is_visible(':text("Welcome, test@example.com")')

5. Локальное тестирование перед push

Pre-commit hook — тесты перед каждым commit:

# .husky/pre-commit
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

echo "Running pre-commit checks..."

# Lint
ruff check . || exit 1
ruff format --check . || exit 1

# Type check
mypy . || exit 1

# Unit tests
pytest tests/unit -q || exit 1

echo "All checks passed!"

Установка:

npm install husky --save-dev
npx husky install
npx husky add .husky/pre-commit "bash scripts/pre-commit.sh"

6. Staging окружение

Deploy на staging для тестирования перед production:

# docker-compose.staging.yml
version: '3.9'
services:
  app:
    image: myapp:${VERSION}
    ports:
      - "8000:8000"
    environment:
      DATABASE_URL: postgresql://user:pass@db-staging:5432/app_staging
      DEBUG: 'false'
      LOG_LEVEL: 'info'
  
  db-staging:
    image: postgres:15
    environment:
      POSTGRES_DB: app_staging
      POSTGRES_USER: user
      POSTGRES_PASSWORD: pass
    volumes:
      - staging_db:/var/lib/postgresql/data

volumes:
  staging_db:

Smoke тесты на staging:

# tests/smoke/test_staging.py
import os
import requests

STAGING_URL = os.getenv('STAGING_URL', 'http://staging.example.com')

def test_api_is_healthy():
    response = requests.get(f'{STAGING_URL}/health')
    assert response.status_code == 200

def test_database_is_accessible():
    response = requests.get(f'{STAGING_URL}/api/v1/users')
    assert response.status_code == 200
    assert isinstance(response.json(), list)

7. Мониторинг в production

Error tracking (Sentry):

import sentry_sdk
from sentry_sdk.integrations.fastapi import FastApiIntegration

sentry_sdk.init(
    dsn=os.getenv('SENTRY_DSN'),
    integrations=[FastApiIntegration()],
    traces_sample_rate=0.1,  # Логируем 10% запросов
    environment=os.getenv('ENVIRONMENT', 'production')
)

# Автоматически отправляет все исключения в Sentry
from fastapi import FastAPI
app = FastAPI()

Логирование:

import logging
from pythonjsonlogger import jsonlogger

logger = logging.getLogger(__name__)
logHandler = logging.StreamHandler()
formatter = jsonlogger.JsonFormatter()
logHandler.setFormatter(formatter)
logger.addHandler(logHandler)

@app.get('/api/v1/users')
async def get_users():
    logger.info('Fetching users', extra={'user_count': 100})
    return {}

8. Чеклист QA процесса

Для каждого feature:

  • Unit тесты написаны (>80% coverage)
  • Integration тесты написаны
  • Code review пройден
  • Тесты проходят в CI/CD
  • Развёрнуто на staging
  • Smoke тесты пройдены
  • Задокументировано (если нужно)
  • Merged в main

Для каждого release:

  • Smoke тесты на production
  • Мониторинг ошибок
  • Проверка логов
  • Проверка метрик (response time, CPU, memory)
  • Rollback план готов

9. Рекомендуемые инструменты

ИнструментЗадачаПример
pytestUnit/Integration тестыpytest tests/ -v
pytest-covCoveragepytest --cov=app
Mock/patchМокирование зависимостейMock(spec=Repository)
PlaywrightE2E тестыpytest tests/e2e/
ruffLintingruff check .
mypyType checkingmypy .
GitHub ActionsCI/CD pipeline.github/workflows/
SentryError trackingsentry.io
PrometheusМетрикиprometheus.io
ELK StackЛогированиеelasticsearch + kibana

Итог

Правильный процесс QA:

  1. Unit тесты — разработчик пишет (TDD)
  2. Integration тесты — взаимодействие компонентов
  3. CI pipeline — автоматический запуск при push
  4. Code review — проверка кода
  5. Staging deploy — smoke тесты
  6. E2E тесты — полный user flow
  7. Production — мониторинг и логирование
  8. Постоянное улучшение — анализ инцидентов

Это обеспечит надёжность и качество вашего проекта!