$ sudo teach IT
Модуль 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, не в обычном билде