Тестирование: cargo test
Тестирование встроено в язык: функции с #[test] и запуск через cargo test.
#[test] — атрибут, помечающий функцию как тест;
cargo testнаходит и запускает все такие функции.
Тесты — часть языка
В Rust не нужна сторонняя библиотека для тестов — поддержка встроена. Тестовая функция помечается атрибутом #[test]. Она проходит, если завершилась без паники, и падает, если паника произошла (например, провалился макрос проверки).
fn add(a: i32, b: i32) -> i32 {
a + b
}
#[test]
fn test_add() {
assert_eq!(add(2, 3), 5); // проверка равенства
assert_eq!(add(-1, 1), 0);
}
#[test]
fn test_add_negative() {
assert!(add(-2, -3) < 0); // проверка условия
}Макросы проверок
В теле теста используют макросы проверок. Если проверка не выполнена — тест паникует и считается проваленным.
| Макрос | Проверяет |
assert!(cond) | что условие истинно |
assert_eq!(a, b) | что a == b |
assert_ne!(a, b) | что a != b |
Запуск
Все тесты запускаются одной командой. Cargo соберёт тестовую версию и выполнит каждую функцию с #[test].
cargo testВывод:
running 2 tests test test_add ... ok test test_add_negative ... ok test result: ok. 2 passed; 0 failed; 0 ignored
Модуль тестов
Принято собирать тесты в отдельный модуль с атрибутом #[cfg(test)] — он означает «компилировать только при тестировании», чтобы тесты не попадали в релизный бинарник. Внутри пишут use super::*;, чтобы видеть тестируемые функции из родительского модуля.
fn is_even(n: i32) -> bool {
n % 2 == 0
}
#[cfg(test)] // компилируется только при cargo test
mod tests {
use super::*; // подтягиваем is_even из внешнего модуля
#[test]
fn even_numbers() {
assert!(is_even(4));
assert!(!is_even(7));
}
}Проверка на панику
Иногда тест должен убедиться, что код паникует при некорректном вводе. Для этого добавляют атрибут #[should_panic].
fn checked_div(a: i32, b: i32) -> i32 {
if b == 0 {
panic!("деление на ноль");
}
a / b
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
#[should_panic]
fn panics_on_zero() {
checked_div(10, 0); // тест пройдёт, потому что здесь ожидается паника
}
}Итог
- Тесты встроены в Rust: функция с
#[test]проходит, если не паникует. - Проверки —
assert!,assert_eq!,assert_ne!; запуск —cargo test. - Тесты держат в модуле
#[cfg(test)];#[should_panic]проверяет ожидаемую панику.