Содержание

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

Разберём, какие бывают автотесты, что покрывать первым и как посчитать, окупаются ли они.

Зачем продукту автотесты?

Автотесты нужны, чтобы каждое изменение можно было выпускать без страха сломать то, что уже работает. Без них каждый релиз требует ручной проверки всего продукта, а со временем команда начинает бояться трогать старый код — и разработка замедляется.

Что дают автотесты:

  • ошибки находятся за минуты после изменения, а не у пользователей;
  • релизы становятся частыми и спокойными;
  • рефакторинг и обновление зависимостей перестают быть рискованными;
  • тесты документируют, как должна работать система;
  • новые разработчики меньше боятся менять чужой код.

Какие бывают автотесты?

Автотесты делятся по уровню: модульные проверяют отдельные функции, интеграционные — работу нескольких частей вместе, включая базу и API, сквозные — целые сценарии через браузер или мобильное приложение. Чем выше уровень, тем ближе тест к реальному пользователю, но тем он медленнее и хрупче.

Тип Что проверяет Скорость Сколько нужно
Модульные Отдельные функции и классы бизнес-логики Миллисекунды Много — для сложной логики
Интеграционные и API Эндпоинты, работа с базой, очередями, интеграции Секунды Основной объём для веб-продукта
Сквозные (E2E) Сценарии пользователя в браузере Секунды и минуты Немного — только критичные сценарии
Контрактные Совместимость API между сервисами и клиентами Секунды Когда есть внешние клиенты или сервисы

Для типичного веб-продукта лучшее соотношение пользы и затрат дают тесты API: они быстрые, проверяют реальную работу с базой и не ломаются при изменении вёрстки.

Разработчик пишет код на ноутбуке Фото: Unsplash

Что покрывать тестами в первую очередь?

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

Пример теста API на Laravel, который проверяет важное правило доступа:

public function test_пользователь_не_видит_чужой_заказ(): void
{
    $owner = User::factory()->create();
    $stranger = User::factory()->create();
    $order = Order::factory()->for($owner)->create();

    $this->actingAs($stranger)
        ->getJson("/api/orders/{$order->id}")
        ->assertNotFound();
}

И пример сквозного теста ключевого сценария в браузере на Playwright:

test('покупатель оформляет заказ', async ({ page }) => {
  await page.goto('/catalog/shoes')
  await page.getByRole('button', { name: 'В корзину' }).first().click()
  await page.getByRole('link', { name: 'Корзина' }).click()
  await page.getByRole('button', { name: 'Оформить заказ' }).click()
  await expect(page.getByText('Заказ оформлен')).toBeVisible()
})

Чего не стоит делать

  • гнаться за процентом покрытия — сто тестов на геттеры не защищают оплату;
  • писать сотни сквозных тестов — они медленные и ломаются от изменения вёрстки;
  • тестировать реализацию вместо поведения — такие тесты мешают рефакторингу.

Сколько стоят автотесты?

Автотесты стоят времени разработчиков: по нашей практике, их написание добавляет к разработке функциональности от 15 до 30% — это ориентир студии, который зависит от сложности логики и требований к надёжности. Окупаются они за счёт меньшего объёма ручной проверки, меньшего числа ошибок в продакшене и более дешёвых изменений в будущем.

Как оценить окупаемость:

  1. Посчитайте, сколько часов уходит на ручную регрессионную проверку перед каждым релизом.
  2. Оцените стоимость ошибок в продакшене: исправления, потерянные заказы, обращения в поддержку.
  3. Сравните с затратами на написание и поддержку тестов.
  4. Учтите, что без тестов стоимость каждого изменения растёт по мере роста продукта.

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

Как встроить автотесты в процесс?

Автотесты встраивают в процесс через CI: они запускаются на каждое изменение, и изменение нельзя слить, пока тесты не пройдут. Тест на исправленную ошибку пишут вместе с исправлением, чтобы ошибка не вернулась.

Правила, которые работают:

  • тесты запускаются автоматически на каждый запрос на слияние;
  • новая бизнес-логика принимается на ревью только с тестами — об этом в статье код-ревью;
  • каждая исправленная ошибка получает тест, воспроизводящий её;
  • нестабильные тесты чинят сразу, иначе команда перестаёт им доверять;
  • тестовые данные создаются фабриками, а не берутся из копии продакшена.

Регулярная работа тестов снижает и стоимость поддержки после запуска — мы разбирали это в статье сколько стоит поддержка сайта и приложения.

Коротко

  • Автотесты нужны, чтобы выпускать изменения без страха сломать работающее.
  • Основной объём для веб-продукта — тесты API и бизнес-логики, сквозных тестов немного.
  • Сначала покрывайте оплату, регистрацию, заказы, права доступа и расчёты.
  • Тесты добавляют к разработке заметную долю времени, но окупаются в продукте, который живёт дольше нескольких месяцев.
  • Запускайте тесты в CI на каждое изменение и пишите тест на каждую исправленную ошибку.

Частые вопросы

  • Какое покрытие кода тестами нужно?

    Универсальной цифры нет. Важнее, чтобы были покрыты критичные сценарии и сложная бизнес-логика. Высокий процент покрытия без тестов на оплату и права доступа защищает хуже, чем меньший, но правильно распределённый.

  • Можно ли добавить автотесты в существующий проект без тестов?

    Да, постепенно: начните со сквозных тестов на самые важные сценарии, затем добавляйте тесты API к каждому изменяемому модулю. Через несколько месяцев критичные части будут покрыты.

  • Заменяют ли автотесты ручное тестирование?

    Нет. Автотесты проверяют то, что уже описано, а ручное тестирование находит неожиданное: неудобный интерфейс, странное поведение на реальных устройствах, ошибки в новых сценариях.