Первые тесты
Здесь будет встроен видео-разбор темы (5–7 минут, YouTube / RuTube / VK Видео) — тем, кто лучше воспринимает на слух, текст ниже не обязателен.
Код, который работает сегодня, легко сломать завтра — одной невинной правкой. Тесты позволяют узнать о поломке за секунды, а не от пользователей: в этой статье напишем первые проверки прямо в песочнице, без установки чего-либо.
Представьте: вы написали функцию, проверили её вручную в консоли — работает. Через неделю вы её «слегка улучшили», и она тихо сломалась. Перепроверять всё руками после каждой правки — тоскливо и ненадёжно, поэтому проверки поручают коду. Тест — это маленькая программа, которая проверяет другую программу.
У тестов две роли. Первая — страховка: меняете код сколько угодно, запускаете тесты и сразу видите, что уцелело, а что нет. Вторая — спецификация: набор тестов читается как список обещаний «эта функция ведёт себя вот так». Тест описывает поведение честнее комментария: устаревший комментарий молчит, а устаревший тест проваливается.
Любой тест — от однострочника до промышленного — устроен одинаково. Есть ожидание: значение, которое должно получиться. Есть факт: то, что код вернул на самом деле. Осталось их сравнить.
true — тест пройден. Появился false — ожидание и реальность разошлись, и это ровно тот момент, ради которого тесты пишут.Не хватает одного: чтобы провал нельзя было проглядеть в потоке вывода. Для этого есть инструмент получше голого console.log.
Метод console.assert(условие, сообщение) работает как строгий, но немногословный проверяющий. Условие истинно — он молчит. Условие ложно — печатает в консоль ошибку с вашим сообщением.
Обратите внимание на две вещи. Успешные проверки не засоряют консоль — видны только провалы. И проваленный assert не останавливает скрипт: выполнятся и все остальные проверки, так что за один запуск вы получаете полную картину.
Напишем функцию pow(x, n), возводящую x в натуральную степень n, и сначала просто посмотрим на неё глазами.
Один запуск «на глаз» — хорошо, но закрепим поведение тестами: три проверки, три разных сочетания аргументов. Функция та же, просто записана в одну строку, чтобы пример был короче.
Тишина перед финальной строкой — это и есть успех. Теперь у pow есть страховка: если кто-нибудь «оптимизирует» цикл и ошибётся, тесты закричат при следующем же запуске.
В настоящих проектах тесты пишут не на console.assert, а с помощью тест-фреймворков — самые популярные сегодня Jest и Vitest. Внутри — то же сравнение ожидания с фактом, но с удобствами: тесты живут в отдельных файлах, у каждого есть человекочитаемое название, а после запуска печатается отчёт — сколько прошло, сколько упало и где именно. Устанавливать их сейчас не нужно: главное, что идея внутри ровно та, которую вы уже освоили.
Во фреймворках проверка выглядит как expect(факт).toBe(ожидание). Звучит солидно, но простейшую версию такой конструкции можно написать за минуту.
С чего начинать проверки? Правило простое: сначала обычные случаи — типичные аргументы, ради которых функция и написана. Потом граничные — значения на краях допустимого: ноль, отрицательные числа, пустая строка. Обычные тесты ловят «функция вообще не работает», граничные — «функция работает, но не всегда».
Граница нашла баг: при отрицательной степени цикл не выполняется ни разу, и функция возвращает 1 вместо 0.5. Все три «обычных» теста из раздела про pow этого не заметили бы никогда. Дальше два честных пути: починить функцию — или договориться, что она работает только при n >= 0, и зафиксировать это отдельным тестом.
| Тип данных | Граничные значения для проверки |
|---|---|
| Числа | 0, отрицательные, очень большие |
| Строки | пустая "", один символ, строка из пробелов |
| Массивы | пустой [], один элемент |
| «Ничего» | undefined, null |
Мнемоника границ: ноль, минус, пусто
- Тест сравнивает ожидание с фактом: совпали — код ведёт себя как задумано.
console.assert(условие, сообщение)молчит при истине, печатает сообщение при лжи и не останавливает скрипт.- Тесты — страховка при изменениях: после любой правки перезапустите их и сразу узнаете, что сломалось.
- Фреймворки вроде Jest и Vitest — те же проверки плюс отчёты и удобства; идея внутри не меняется.
- Порядок кейсов: сначала обычные, потом граничные — ноль, отрицательные, пустые значения.
1/3Что появится в консоли после console.assert(5 > 3, "ошибка")?
2/3Функция pow из статьи (версия с циклом) — что вернёт pow(2, -3)?
3/3Тест через console.assert провалился. Что происходит со скриптом?
Допишите isEmpty
Напишите функцию isEmpty(str), которая возвращает true для пустой строки и false для любой другой. Тесты уже готовы — ваша задача заставить их замолчать.
Достаточно одного сравнения: return str === "";. После этого оба console.assert перестанут выводить ошибки — тишина и есть успех.
Поймайте баг границей
Функция firstChar возвращает первый символ строки. На обычных строках она работает, но один граничный случай выдаёт undefined. Напишите console.assert, фиксирующий желаемое поведение — для пустой строки пусть возвращается пустая строка, — и почините функцию.
Тест: console.assert(firstChar("") === "", "пустая строка");. Починка: return str.length > 0 ? str[0] : ""; — граница закрыта и закреплена тестом навсегда.