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

В чем разница между интеграционным и End-to-end тестом?

2.3 Middle🔥 151 комментариев
#JavaScript Core

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

🐱
claude-haiku-4.5PrepBro AI2 апр. 2026 г.(ред.)

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

Разница между интеграционным и End-to-End тестом

Контекст: Пирамида тестирования

       E2E (End-to-End)
      /              \
   Integration     Integration
   /                   \
Unit             Unit

Есть три уровня тестов, каждый проверяет разное:

Unit тесты - тестируют отдельные функции/компоненты Integration тесты - тестируют взаимодействие между компонентами/модулями E2E тесты - тестируют весь пользовательский сценарий от начала до конца

Unit vs Integration vs E2E

// Пример: функция загрузки и отображения пользователя

// UNIT тест - тестируем функцию парсирования отдельно
test('parseUser должна разобрать JSON', () => {
  const data = { id: 1, name: 'Alice' };
  const result = parseUser(data);
  expect(result.name).toBe('Alice');
});

// INTEGRATION тест - тестируем fetch + парсирование
test('loadUser должна загрузить и спарсить пользователя', async () => {
  const user = await loadUser(1);
  expect(user.name).toBe('Alice');
});

// E2E тест - тестируем весь сценарий: нажимаем кнопку -> видим пользователя
test('пользователь видит данные после нажатия кнопки', async () => {
  await page.goto('http://localhost:3000');
  await page.click('[data-testid="load-user"]');
  await page.waitForSelector('[data-testid="user-name"]');
  const name = await page.textContent('[data-testid="user-name"]');
  expect(name).toBe('Alice');
});

Integration тесты

Integration тест проверяет взаимодействие между несколькими компонентами или системами. Части работают вместе.

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

  • Тестируют несколько компонентов в одном тесте
  • Используют реальные или мок-зависимости
  • Быстрее E2E, медленнее Unit
  • Не требуют запущенного приложения
  • Проверяют бизнес-логику на уровне выше чем Unit

Пример Integration теста (React):

// components/UserProfile.tsx
export function UserProfile({ userId }: { userId: number }) {
  const [user, setUser] = useState(null);
  const [loading, setLoading] = useState(true);

  useEffect(() => {
    fetchUser(userId).then((data) => {
      setUser(data);
      setLoading(false);
    });
  }, [userId]);

  if (loading) return <div>Loading...</div>;
  return <div>{user?.name}</div>;
}

// Integration тест
import { render, screen, waitFor } from '@testing-library/react';
import * as api from './api';

test('UserProfile загружает и показывает пользователя', async () => {
  // Мокируем API
  jest.spyOn(api, 'fetchUser').mockResolvedValue({
    id: 1,
    name: 'Alice'
  });

  render(<UserProfile userId={1} />);

  // Проверяем, что компонент делает:
  // 1. Показывает Loading
  expect(screen.getByText('Loading...')).toBeInTheDocument();

  // 2. Загружает данные
  // 3. Показывает имя
  await waitFor(() => {
    expect(screen.getByText('Alice')).toBeInTheDocument();
  });
});

End-to-End (E2E) тесты

E2E тест проверяет полный сценарий пользователя, как если бы реальный человек использовал приложение.

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

  • Тестируют весь user journey от начала до конца
  • Взаимодействуют с браузером через Playwright, Cypress, WebDriver
  • Используют реальное приложение (не моки)
  • Медленнее чем Unit и Integration
  • Требуют запущенного приложения
  • Проверяют, что система работает как единое целое

Пример E2E теста (Playwright):

// e2e/user-profile.spec.ts
import { test, expect } from '@playwright/test';

test('пользователь может загрузить профиль', async ({ page }) => {
  // 1. Открываем приложение
  await page.goto('http://localhost:3000');

  // 2. Кликаем на кнопку "Load Profile"
  await page.click('button:has-text("Load Profile")');

  // 3. Видим loading состояние
  const loader = page.locator('text=Loading');
  await expect(loader).toBeVisible();

  // 4. Ждем загрузки данных
  const userName = page.locator('text=Alice');
  await expect(userName).toBeVisible();

  // 5. Проверяем, что профиль отображается корректно
  await expect(page.locator('[data-testid="user-email"]')).toContainText('alice@example.com');
  await expect(page.locator('[data-testid="user-avatar"]')).toBeVisible();
});

Сравнение

ПараметрIntegrationE2E
Что тестируютВзаимодействие компонентовПолный сценарий пользователя
Какие части используютНесколько компонентов/модулейВсё приложение
Требуется приложениеНет (можно тестировать части)Да (приложение должно запуститься)
ЗависимостиМогут быть моки (БД, API)Реальные зависимости (БД, API)
СкоростьСредняя (100мс - 1сек)Медленная (1сек - 10сек на тест)
ИнструментыJest, Vitest, Testing LibraryPlaywright, Cypress, Selenium
Что проверяютЛогика и взаимодействиеВизуальное отображение и UX
Сложность написанияСредняяВысокая
Количество тестовМногоМеньше (критичные сценарии)

Практические примеры

Integration тест - форма заказа:

test('форма заказа отправляет корректные данные', async () => {
  const submitMock = jest.fn();
  const { getByRole, getByLabelText } = render(
    <OrderForm onSubmit={submitMock} />
  );

  // Заполняем форму
  const nameInput = getByLabelText('Name');
  fireEvent.change(nameInput, { target: { value: 'Alice' } });

  const priceInput = getByLabelText('Price');
  fireEvent.change(priceInput, { target: { value: '100' } });

  // Отправляем форму
  const submitBtn = getByRole('button', { name: /submit/i });
  fireEvent.click(submitBtn);

  // Проверяем, что вызвана колбэк с правильными данными
  expect(submitMock).toHaveBeenCalledWith({
    name: 'Alice',
    price: 100
  });
});

E2E тест - полный сценарий заказа:

test('пользователь может создать заказ', async ({ page }) => {
  // Переходим на страницу
  await page.goto('http://localhost:3000/orders');

  // Заполняем форму
  await page.fill('input[name="name"]', 'Alice');
  await page.fill('input[name="price"]', '100');

  // Отправляем форму
  await page.click('button:has-text("Create Order")');

  // Проверяем, что заказ создан
  await page.waitForURL('**/orders/confirmation');
  await expect(page.locator('text=Order created successfully')).toBeVisible();

  // Проверяем БД
  const order = await db.orders.findLast();
  expect(order.name).toBe('Alice');
  expect(order.price).toBe(100);
});

Когда какой тест использовать?

Integration тесты для:

  • Проверки взаимодействия компонентов
  • Валидации бизнес-логики
  • Проверки работы с API (моки)
  • Тестирования форм и их обработки

E2E тесты для:

  • Критичных сценариев (авторизация, оплата)
  • Проверки визуального отображения
  • Кроссбраузерных тестов
  • User journeys (регистрация -> покупка -> отзыв)

Пирамида тестов:

  • 70% Unit тесты (быстрые, дешевые)
  • 20% Integration тесты (проверяют взаимодействие)
  • 10% E2E тесты (критичные сценарии)

Заключение

  • Integration тест = несколько компонентов вместе (но не весь сценарий)
  • E2E тест = полный пользовательский сценарий от начала до конца
  • Используй оба типа для полного покрытия
  • E2E медленнее, но ловит больше реальных проблем
  • Integration быстрее, ловит проблемы на уровне компонентов
В чем разница между интеграционным и End-to-end тестом? | PrepBro