Что именно тестировать
Урок помогает решить, какой код стоит покрывать тестами в первую очередь, а какой — нет.
Тестируйте поведение и логику, особенно граничные случаи, а не тривиальный код и не детали реализации.
Приоритет: ценная логика
В первую очередь покрывают код, где легко ошибиться и где ошибка дорого стоит:
- Бизнес-логика: расчёт цен, скидок, прав доступа, валидация.
- Утилиты: форматтеры дат, парсеры, преобразования данных.
- Граничные случаи: пустой ввод, ноль, отрицательные числа, очень большие значения,
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Запрещать рефакторинг