Перейти к основному содержимому

Небольшие правила, большая разница

Хорошие тесты следуют нескольким привычкам:

1. Понятные имена — greet falls back for an empty name говорит, что сломалось, без открытия файла.
2. Одно поведение на тест — маленькие тесты указывают прямо на проблему.
3. Таблицы для множества случаев — один цикл вместо скопированных тестов.
4. Сообщения с got и want — сбой должен объяснять себя сам.
5. Отдельные тесты, чтобы увидеть всё; один тест там, где продолжать бессмысленно.
6. Запускайте тесты часто — после каждого небольшого изменения, а не один раз в конце.
7. Тесты живут рядом с кодом — та же папка, суффикс .test.ts.


Сообщения о сбоях, которые помогают

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

Хорошая форма — func(input) = got; want want. Оборачивание строк в JSON.stringify добавляет вокруг них кавычки, поэтому пропущенный пробел или пропущенная запятая сразу видны.

Сообщение со всей историей

greet возвращает неправильное приветствие. Наше сообщение показывает вызов, полученное и ожидаемое значение, а исполнитель тестов добавляет ниже свои строки + actual - expected — ошибка (неправильное слово, пропущенные запятая и восклицательный знак) видна по одному только выводу, без открытия кода.

Prompt
Напишите файл тестов на TypeScript, где функция greet возвращает неправильное приветствие («Здравствуй Ana» вместо «Привет, Ana!»), а тест сообщает о сбое как о вызове, полученном значении и ожидаемом значении, используя JSON.stringify, чтобы строки были в кавычках. Покажите настоящий вывод упавшего теста.
Вывод: программа на TypeScript и захваченный вывод

Одно поведение на тест

У теста, который проверяет пять вещей, есть пять причин упасть — а его имя может описать только одну из них. Разделение по поведению делает каждый тест маленьким, а его имя — честным. Здесь это важно вдвойне, потому что упавшая проверка останавливает свой тест: пять проверок в одном тесте означают, что вы всегда увидите только первый сбой.

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

Два поведения — два теста

greet uses the name проверяет обычный случай, greet falls back for an empty name — запасной вариант. Вывод перечисляет их отдельно — сбой указал бы ровно на одно поведение.

Prompt
Напишите файл тестов на TypeScript с функцией greet, которая приветствует по имени и возвращает запасное «Привет, незнакомец!» для пустого имени. Напишите два отдельных сфокусированных теста, по одному на каждое поведение, с именами, которые говорят, что они проверяют. Покажите проходящий вывод, где перечислены оба теста.
Вывод: программа на TypeScript и захваченный вывод

Сколько проверено: покрытие

node --test --experimental-test-coverage измеряет, какую часть вашего кода тесты действительно выполняют. Он печатает по одной строке на файл с тремя процентами — строки, ветви и функции — плюс номера строк, до которых ничего не дошло.

Это число — компас, а не цель: низкое значение показывает непроверенные пути. Покрытие 100% не доказывает, что код правильный, но непокрытые строки гарантированно не проверены.

Измеряем покрытие

У describeTemperature три ветви, а тест задействует одну. Отчёт сообщает line % 76.47 и branch % 60.00 и называет непокрытые строки 6-7 9-10 — возврат мороз и возврат жара. Тесты для холодной и горячей ветви подняли бы оба числа.

Измеряется весь файл, включая тесты, и поэтому число для строк не ниже: сами строки тестов все выполнились.

Prompt
Напишите файл тестов на TypeScript с функцией describeTemperature, которая в зависимости от температуры возвращает «мороз», «умеренно» или «жара», и одним тестом, который проверяет только ветвь «умеренно». Покажите вывод её запуска с экспериментальной опцией покрытия у исполнителя тестов, включая таблицу покрытия.
Вывод: программа на TypeScript и захваченный вывод
Measure the coverage