Что именно тестировать

Урок помогает решить, какой код стоит покрывать тестами в первую очередь, а какой — нет.

Тестируйте поведение и логику, особенно граничные случаи, а не тривиальный код и не детали реализации.

Приоритет: ценная логика

В первую очередь покрывают код, где легко ошибиться и где ошибка дорого стоит:

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

Граничные случаи — где живут баги

Большинство ошибок прячется на границах. Проверим утилиту усечения строки на краях:

function truncate(str, max) {
  if (str.length <= max) return str;
  return str.slice(0, max) + '\u2026';
}

function assert(actual, expected, name) {
  console.log((actual === expected ? '\u2713 passed' : '\u2717 FAILED') +
    ': ' + name + ' \u2192 "' + actual + '"');
}

assert(truncate('', 5), '', 'пустая строка');
assert(truncate('abc', 5), 'abc', 'короче лимита');
assert(truncate('abcde', 5), 'abcde', 'ровно по лимиту');
assert(truncate('abcdef', 5), 'abcde\u2026', 'длиннее лимита');

Вывод:

✓ passed: пустая строка → ""
✓ passed: короче лимита → "abc"
✓ passed: ровно по лимиту → "abcde"
✓ passed: длиннее лимита → "abcde…"

Главный риск — граница «ровно по лимиту»: тут часто ошибаются на единицу (off-by-one). Отдельный тест на неё защищает от такой ошибки.

Что обычно НЕ тестируют отдельно

  • Тривиальные геттеры/сеттеры без логики — тест ничего не докажет.
  • Чужой код (фреймворк, библиотека) — это уже протестировано авторами.
  • Детали реализации (приватные переменные, конкретные имена методов) — тест должен проверять результат, а не «как именно» он получен.

Тестируйте контракт, а не внутренности

Хороший тест проверяет наблюдаемое поведение: вход → выход, побочный эффект. Если тест ломается при безобидном рефакторинге, который не меняет поведение, — он завязан на реализацию и хрупок.

Практическое правило

Начните с «горячих» мест: где сложная логика, где недавно были баги, где цена ошибки высока. Не гонитесь за 100% — гонитесь за уверенностью в важном.

Итог

  • Покрывайте бизнес-логику, утилиты и особенно граничные случаи.
  • Границы (ноль, пусто, off-by-one) — главный источник багов.
  • Не тестируйте тривиальный и чужой код и детали реализации.
  • Проверяйте контракт (вход → выход), а не внутреннее устройство.
Проверьте себя
1. Какой код стоит покрывать тестами в первую очередь?
AТривиальные геттеры без логики
BБизнес-логику, утилиты и граничные случаи
CКод фреймворка
DКомментарии
2. Почему важно тестировать граничные случаи?
AОни выглядят красиво в отчёте
BБольшинство багов (например off-by-one) прячется именно на границах
CТак требует npm
DГраничные тесты быстрее
3. Что значит «тестировать контракт, а не детали реализации»?
AПроверять приватные переменные
BПроверять вход → выход и поведение, а не то, как именно оно получено
CТестировать только сторонние библиотеки
DЗапрещать рефакторинг
Поддержать проект