Shanraq.org Shanraq.org
Первый автоматический тест
IT

Rust: с нуля до своего органайзера Урок 16 из 20

Первый автоматический тест

Урок 16. Проверить расчёт функцией, которая сама сообщает о неверном результате.

Текст переведён с помощью ИИ.

Предварительно: уроки 1–15, особенно функции и массивы. Цель — поймать ошибку в функции до использования сводки. Пока тестируем числа, без новых библиотек.

Образ и опорная карта

Ручная проверка похожа на повторное взвешивание одной посылки. Автоматический тест — сохранённое правило «для такого входа ожидаю такой результат», которое можно запускать после каждого изменения. Оно проверяет выбранные случаи, а не доказывает правильность всех возможных входов.

Вход → функция → фактический результат ↔ ожидаемый результат → сообщение теста. Воспроизведите эту цепочку по памяти, прежде чем смотреть код.

Подготовка и первый запуск

Заранее разберём два новых обозначения. #[test]атрибут, метка перед функцией без аргументов. # начинает метку, квадратные скобки содержат её имя, а test означает «запустить следующую функцию как тест». assert_eq!(фактическое, ожидаемое) — макрос сравнения: первый аргумент вычисляется кодом, второй задаём мы. ! обозначает макрос, как в println!. При равенстве проверка проходит; при неравенстве показывает оба значения и проваливается.

В проекте organizer из урока 6, в папке с Cargo.toml, сохраните прежний src/main.rs отдельно и замените его целиком кодом ниже. Другие файлы не меняем. cargo run собирает и запускает обычную программу; cargo test собирает и запускает функции с атрибутом #[test]. Обе команды вводятся в терминале проекта. Вывод ниже относится только к cargo run; сообщения тестового запуска могут отличаться по версии инструмента.

fn remaining(total: u32, done: u32) -> u32 {
    total - done
}

fn main() {
    println!("Осталось: {}", remaining(7, 2));
}

#[test]
fn subtracts_done_tasks() {
    assert_eq!(remaining(7, 2), 5);
}
Осталось: 5

cargo test найдёт функцию по метке; main её не вызывает. Тест находится в том же файле и может вызвать remaining, объявленную выше. Группировать тесты в отдельный модуль научимся в уроке 44.

assert_eq! ничего не печатает при успехе. cargo test должен сообщить 1 passed; 0 failed; остальные строки зависят от версии Cargo. Тест не исправляет функцию сам.

Намеренно сломайте и восстановите

Поменяйте в тесте ожидаемое 5 на 6 и выполните cargo test: тест должен провалиться. Верните 5. Затем поменяйте реализацию на total + done: снова получите провал. Верните вычитание. Если done > total, вычитание u32 нарушает предусловие урока 14; эта функция предназначена только для done <= total. Обработку неверного ввода добавим после Result.

Проверьте себя

Что запускает cargo run, а что — cargo test? Может ли один успешный тест доказать, что функция верна для любого u32? Ответ: первый запускает main, второй — тестовые функции; нет. Попробуйте ответить без карты.

Задание

Обязательное. Напишите функцию is_short(minutes: u32) -> bool по правилу урока 14: от 1 до 15 включительно. Добавьте три теста: 0 → false, 15 → true, 16 → false. Сначала запишите ожидаемые результаты, затем выполните cargo test. Обычная программа должна вывести Короткая: true для 15. Измените один ожидаемый результат, убедитесь в провале и верните его. Если забыли синтаксис условия, вернитесь к уроку 11.

Подсказка

Каждая проверка — отдельная функция с #[test] в том же файле, после main. Сравнивайте результат is_short(...) с true или false.

Эталон после попытки

fn is_short(minutes: u32) -> bool {
    minutes > 0 && minutes <= 15
}

fn main() {
    println!("Короткая: {}", is_short(15));
}

#[test]
fn zero_is_not_a_task() {
    assert_eq!(is_short(0), false);
}

#[test]
fn fifteen_is_short() {
    assert_eq!(is_short(15), true);
}

#[test]
fn sixteen_is_long() {
    assert_eq!(is_short(16), false);
}
Короткая: true

Эталон показывает три разные границы, поскольку один пример с 15 не обнаружил бы принятие нуля или 16. Справка по тестам Rust.

Предыдущий урок · Оглавление

Если вы нашли ошибку или опечатку в тексте статьи, то сообщите нам об этом

Комментарии (0)

Пока нет комментариев. Будьте первым.