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

Какие знаешь уровни пирамиды тестирования?

1.0 Junior🔥 201 комментариев
#Тестирование

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

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

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

# Уровни пирамиды тестирования

Пирамида тестирования — это концептуальная модель, разработанная Майком Коном, которая показывает оптимальное распределение тестов по уровням абстракции. Это одна из ключевых концепций в разработке, обеспечивающей эффективность и скорость тестирования.

Классическая модель: три уровня

1. Unit-тесты (основание пирамиды)

Это наибольшее количество тестов, тестирующих отдельные функции, методы и компоненты в изоляции.

Характеристики:

  • Быстрое выполнение (миллисекунды)
  • Максимальное покрытие логики
  • Использование мокирования зависимостей
  • Тестирование граничных случаев
import pytest
from unittest.mock import Mock, patch

def calculate_discount(price: float, is_member: bool) -> float:
    if is_member:
        return price * 0.9
    return price

def test_calculate_discount_member():
    assert calculate_discount(100, True) == 90.0

def test_calculate_discount_non_member():
    assert calculate_discount(100, False) == 100.0

def test_calculate_discount_edge_case():
    assert calculate_discount(0, True) == 0.0

Рекомендации:

  • Один assert на тест (или assertion на одно понятие)
  • Используй AAA паттерн: Arrange, Act, Assert
  • Мокируй внешние зависимости (БД, API, файловая система)
  • Покрытие должно быть > 80-90%

2. Integration-тесты (средний слой)

Тестируют взаимодействие нескольких компонентов: работу с БД, внешними API, сервисами.

Характеристики:

  • Среднее время выполнения (секунды)
  • Тестирование реальных интеграций
  • Использование тестовых версий внешних сервисов
  • Проверка потоков данных между компонентами
import pytest
from sqlalchemy.orm import Session
from app.models import User
from app.services import UserService

@pytest.fixture
def db_session():
    session = create_test_session()
    yield session
    session.rollback()

def test_create_user_integration(db_session: Session):
    service = UserService(db_session)
    user_data = {"email": "test@example.com", "name": "John"}
    user = service.create_user(**user_data)
    db_session.commit()
    assert user.id is not None
    assert user.email == "test@example.com"
    retrieved = db_session.query(User).filter_by(id=user.id).first()
    assert retrieved is not None

Рекомендации:

  • Используй фикстуры для подготовки данных
  • Используй VCR.py или requests_mock для записи/воспроизведения HTTP запросов
  • Изолируй тестовые данные (не пересекайся с другими тестами)
  • Чистка данных после каждого теста

3. E2E-тесты (вершина пирамиды)

Тестируют всю систему с точки зрения пользователя, от UI до БД.

Характеристики:

  • Медленное выполнение (десятки секунд)
  • Минимальное количество тестов
  • Тестирование критических сценариев
  • Использование реального браузера или полного окружения
import pytest
from playwright.async_api import async_playwright

@pytest.mark.asyncio
async def test_user_registration_flow():
    async with async_playwright() as p:
        browser = await p.chromium.launch()
        page = await browser.new_page()
        await page.goto("http://localhost:3000/register")
        await page.fill('input[name="email"]', "newuser@test.com")
        await page.fill('input[name="password"]', "SecurePass123!")
        await page.fill('input[name="name"]', "John Doe")
        await page.click('button:has-text("Register")')
        await page.wait_for_url("http://localhost:3000/dashboard")
        assert "Dashboard" in await page.title()
        await browser.close()

Рекомендации:

  • Тестируй только критические user journeys
  • Используй page object model для структурирования кода
  • Реши в начале: браузер-тесты или API-тесты для E2E
  • Обработай flakiness с помощью waits и retries

Современная модель: четыре уровня

Некоторые компании добавляют четвёртый уровень для более детального разделения:

E2E (1%)
Contract Tests (5%)
Integration Tests (15%)
Unit Tests (80%)

Contract-тесты (новый уровень)

Проверяют контракт между микросервисами или компонентами:

def test_user_api_contract():
    response = client.get("/api/users/1")
    assert "id" in response
    assert "name" in response
    assert isinstance(response["id"], int)

Распределение усилий и времени

Unit Tests:

  • 70-80% от всех тестов
  • 10% времени выполнения
  • Максимальный ROI

Integration Tests:

  • 15-25% от всех тестов
  • 60% времени выполнения
  • Покрытие критических путей

E2E Tests:

  • 5-10% от всех тестов
  • 30% времени выполнения
  • Только главные сценарии

Анти-паттерны

Перевёрнутая пирамида — много E2E-тестов, мало Unit-тестов:

Проблемы:

  • Очень медленная feedback loop (часы)
  • Flaky тесты (нестабильные)
  • Высокие затраты на поддержку

Практические советы

  1. Начни с unit-тестов — они дешёвые и быстрые
  2. Покрой интеграции — убедись, что компоненты работают вместе
  3. E2E только для критического — используй для главных юзер-джорни
  4. Параллелизуй выполнение — unit-тесты должны запускаться в CI за минуты
  5. Мониторь скорость — если тесты замедляются, оптимизируй архитектуру

Заключение

Пирамида тестирования — это не жёсткое правило, а руководство для построения эффективной стратегии тестирования. Ключевой принцип: много быстрых юнит-тестов, умеренно интеграционных, и минимум медленных E2E-тестов. Это обеспечивает быструю feedback loop для разработчиков и надёжность продакшена.