Какие знаешь уровни пирамиды тестирования?
Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
# Уровни пирамиды тестирования
Пирамида тестирования — это концептуальная модель, разработанная Майком Коном, которая показывает оптимальное распределение тестов по уровням абстракции. Это одна из ключевых концепций в разработке, обеспечивающей эффективность и скорость тестирования.
Классическая модель: три уровня
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 тесты (нестабильные)
- Высокие затраты на поддержку
Практические советы
- Начни с unit-тестов — они дешёвые и быстрые
- Покрой интеграции — убедись, что компоненты работают вместе
- E2E только для критического — используй для главных юзер-джорни
- Параллелизуй выполнение — unit-тесты должны запускаться в CI за минуты
- Мониторь скорость — если тесты замедляются, оптимизируй архитектуру
Заключение
Пирамида тестирования — это не жёсткое правило, а руководство для построения эффективной стратегии тестирования. Ключевой принцип: много быстрых юнит-тестов, умеренно интеграционных, и минимум медленных E2E-тестов. Это обеспечивает быструю feedback loop для разработчиков и надёжность продакшена.