Модуль 3 · Команды Cargo
Тестирование
cargo test — встроенный в Cargo тест-раннер. Никаких дополнительных инструментов не нужно.
🧪 Практика
🕐 ~25 минут
✅
cargo test — основные команды
Терминал
cargo test # запустить все тесты
cargo test имя_теста # запустить тесты с именем, содержащим строку
cargo test -- --nocapture # показывать println! внутри тестов
cargo test -- --test-threads=1 # запустить тесты последовательно (не параллельно)
cargo test --test integration # запустить файл tests/integration.rs
cargo test --doc # запустить только документационные тесты
cargo test --lib # только юнит-тесты из src/
cargo test -p my_crate # тесты конкретного крейта в воркспейсе
📂
Три вида тестов в Rust
1. Юнит-тесты — прямо в src/
src/lib.rs или src/main.rs
pub fn add(a: i32, b: i32) -> i32 {
a + b
}
#[cfg(test)] // этот блок компилируется только при cargo test
mod tests {
use super::*; // импортируем из родительского модуля
#[test] // эта функция — тест
fn test_add() {
assert_eq!(add(2, 3), 5);
}
#[test]
fn test_add_negative() {
assert_eq!(add(-1, 1), 0);
}
}
Имеют доступ к приватным функциям модуля. Идеальны для тестирования внутренней логики.
2. Интеграционные тесты — папка tests/
tests/integration_test.rs
// Каждый файл в tests/ — отдельный крейт
// Доступны только публичные функции вашей библиотеки
use my_crate::add;
#[test]
fn test_public_api() {
assert_eq!(add(10, 20), 30);
}
Тестируют публичный API как внешний пользователь. Каждый файл в
tests/ — отдельная программа.3. Документационные тесты — в комментариях
src/lib.rs
/// Складывает два числа.
///
/// # Examples
///
/// ```
/// use my_crate::add;
/// assert_eq!(add(2, 3), 5); // этот код реально запускается при cargo test
/// ```
pub fn add(a: i32, b: i32) -> i32 {
a + b
}
Примеры в документации автоматически становятся тестами. Гарантирует что примеры в доках всегда актуальны.
⚡
Макросы проверок
Встроенные assert-макросы
assert!(condition) // паника если condition == false
assert_eq!(left, right) // паника если left != right
assert_ne!(left, right) // паника если left == right
assert!(cond, "сообщение {}", val) // своё сообщение при падении
// Ожидание паники:
#[test]
#[should_panic(expected = "деление на ноль")]
fn test_divide_by_zero() {
divide(10, 0);
}
// Пропустить тест:
#[test]
#[ignore = "требует сетевого соединения"]
fn test_network() { }
📌 Что важно запомнить
→ Три вида тестов: юнит (в src/), интеграционные (в tests/), документационные (в ///)
→ cargo test имя — запускает тесты с именем, содержащим подстроку
→ -- --nocapture — показывает println! внутри тестов
→ #[cfg(test)] — блок компилируется только при cargo test, не в обычном билде