Тестирование кода: модульные тесты и утверждения
Докажите, что ваши функции работают, и сохраните их работоспособность при рефакторинге
Главная идея: модульный тест - это крошечная программа, которая вызывает один небольшой фрагмент вашего кода с известными входными данными и проверяет, что он выдаёт ожидаемый результат. Вместо того чтобы всматриваться в экран и каждый раз вручную решать, "выглядит ли результат правильно", вы пишете проверку один раз и позволяете компьютеру выполнять её за вас снова и снова. Когда изменение спустя месяцы сломает поведение, упавший тест сразу же укажет вам на это, на конкретной строке, вместо того чтобы пользователь обнаружил ошибку в продакшене.
К концу вы сможете:
- писать утверждения, которые прямо в коде выражают то, что должно быть истинным;
- строить любой тест по шаблону Arrange-Act-Assert (Подготовка-Действие-Проверка);
- осознанно выбирать граничные случаи, которые с наибольшей вероятностью выявят ошибки;
- создавать небольшой независимый от фреймворка тестовый каркас на чистом C++ и читать его отчёт об успехах и провалах.
Вы уже пишете программы из многих функций. Тестирование - это профессиональная привычка, которая позволяет доверять им и менять их без страха. Чтобы начать, не нужна внешняя библиотека: стандартный C++ даёт всё необходимое.
1. Зачем вообще писать тесты?
Тестирование "вручную", запустить программу, ввести данные и прочитать вывод, работает ровно один раз. Оно не масштабируется и никогда не защитит вас завтра. Автоматические тесты дают четыре конкретных преимущества:
- Защита от регрессий. Регрессия - это ошибка, которая снова появляется в коде, ранее работавшем. Тест, прошедший вчера и упавший сегодня, указывает точно на то поведение, которое сломало ваше изменение.
- Страховка при рефакторинге. Вы можете перестраивать код, переименовывать, разбивать функцию, менять алгоритм, и снова запускать тесты. Если они по-прежнему проходят, наблюдаемое поведение не изменилось. Это главная причина, по которой опытные инженеры пишут тесты.
- Исполняемая документация. Хороший тест говорит: "при этом входе ответ - такой". Новый читатель понимает, как должна использоваться функция, гораздо быстрее, чем из прозы.
- Быстрая обратная связь. Набор тестов выполняется за миллисекунды и проверяет десятки случаев, которые вы никогда не стали бы перепроверять вручную.
Аналогия. Пилот проходит один и тот же письменный чек-лист перед каждым полётом. Дело не в забывчивости; дело в том, что фиксированный, повторяемый набор проверок ловит ту единственную проблему, которую пропустил бы уставший человеческий глаз. Ваш набор тестов - это такой чек-лист для вашего кода.