Раздел 41 · Zig с нуля

Встроенное тестирование

junior~10 мин

без входаВойди, чтобы отмечать прогресс, вести заметки и решать задачи в редакторе. войти

Встроенное тестирование

Когда собираешь мебель, сначала проверяешь, держится ли один угол, а не садишься на готовый шкаф. Маленькая проверка делает причину поломки ближе. В коде тест сравнивает конкретное обещание с наблюдаемым результатом.

Наше обещание простое: ограничить число диапазоном яркости от 0 до 255. Проверим середину, обе границы и входы снаружи.

Одна мысль урока

Тест исполняет отдельный пример договора и проваливается при несовпадении.

Опора из прошлого урока: Коллекции: ArrayList и HashMap.

От картинки к записи

Тест

в Zig начинается с test "имя". Для его запуска используется zig test file.zig. Не нужна отдельная функция main: компилятор собирает тестовую программу с собственным способом запуска блоков.

Хорошее имя называет поведение, а не номер вроде test1. Если проверка провалится, фраза clamp boundaries сразу подскажет, какой договор нарушился. Это особенно полезно, когда в файле десятки примеров. Название не заменяет реальные ожидания, но помогает найти их.

std.testing.expect проверяет логическое условие. expectEqual сравнивает значения, expectEqualStrings байты строк, expectEqualSlices элементы последовательности. expectError проверяет ошибочный результат. Для дробных вычислений есть проверки приблизительного равенства: прямое сравнение может не соответствовать задаче из-за округления представления.

Все эти проверки могут вернуть ошибку. Поэтому перед ними ставим try, чтобы тест не проигнорировал неуспех. В тестовом блоке возврат ошибки означает провал, а не правильный результат предметной функции. Это два уровня, которые мы уже разделяли при работе с error union.

В примере функция clamp принимает i32. Отрицательные входы допустимы, но результат ограничен u8. Сначала выбираем границу, затем выполняем @intCast. Без этого порядка преобразование отрицательного числа само было бы нарушением договора. Тест должен различать правильную обработку и случайное попадание маленького положительного входа.

Граничные значения ищем по условию. У нас условия < 0 и > 255: значит важны -1, 0, 255 и 256. Значение 42 проверяет обычную середину. Это не случайный список любимых чисел; каждый пример исследует переход между путями.

Тестовый аллокатор обнаруживает утечки в тестах, где используется динамическая память. Если числовая функция не выделяет память, специально добавлять аллокатор ей не нужно. Проверка должна отражать реальную задачу, а не создавать ресурсы ради демонстрации инструмента.

Успешный тест не доказывает правильность всех входов. Он проверяет выбранные случаи. Чем яснее договор и устройство алгоритма, тем проще выбрать различающие примеры. Если тест только сравнивает функцию с её собственной копией, обе могут повторять одну ошибку. Ожидания должны происходить из требований или ручного расчёта.

Флаг --test-filter оставляет подходящие по имени проверки. Это полезно для работы с одним случаем, но перед завершением нужно запускать полный набор: узкий фильтр может пропустить соседнюю поломку. Тесты из импортируемых модулей должны быть доступны анализу; большой проект позже подключит их явным корневым тестом.

премиум-урок

Продолжение в премиуме: 1 200 ₽ в месяц или 10 000 ₽ в год. Вместе с ним серверные проверки задач и школьные токены AI-коуча.

Оплата пока не подключена: премиум и курсы открываются промокодом.