Rust:
Письмо тестів

Як це зробити:

Вбудований фреймворк тестування Rust підтримує модульні, інтеграційні та документаційні тести без необхідності в зовнішніх бібліотеках. Тести позначаються за допомогою #[test], і будь-яка функція, позначена так, компілюється як тест.

Написання модульного тесту:

Розмістіть модульні тести у модулі, який вони тестують, використовуючи підмодуль tests, позначений #[cfg(test)], щоб забезпечити їх компіляцію лише під час тестування.

// lib.rs або main.rs
pub fn add(a: i32, b: i32) -> i32 {
    a + b
}

#[cfg(test)]
mod tests {
    use super::*;

    #[test]
    fn it_adds_two() {
        assert_eq!(add(2, 2), 4);
    }
}

Запуск тестів:

$ cargo test

Вивід:

   Сompiling your_package_name v0.1.0 (/path/to/your_package)
    Finished test [unoptimized + debuginfo] target(s) in 0.00 secs
     Running unittests src/lib.rs (або src/main.rs)

running 1 test
test tests::it_adds_two ... ok

test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out

Написання інтеграційних тестів:

Інтеграційні тести розміщуються у каталозі tests на верхньому рівні вашого проекту, поруч із src. Кожен файл .rs у tests компілюється як окрема самостійна крейт.

// tests/integration_test.rs
use your_package_name;

#[test]
fn it_adds_two() {
    assert_eq!(your_package_name::add(2, 2), 4);
}

Тестування з популярними бібліотеками сторонніх розробників:

Для більш широких можливостей тестування бібліотека proptest може генерувати широкий спектр вхідних даних для тестування функцій.

Додайте proptest як залежність для розробки в Cargo.toml:

[dev-dependencies]
proptest = "1.0"

Використовуйте proptest для запуску одного і того ж тесту з багатьма автоматично генерованими вхідними даними:

// всередині tests/integration_test.rs або модуля #[cfg(test)]

use proptest::prelude::*;

proptest! {
    #[test]
    fn doesnt_crash(a: i32, b:i32) {
        your_package_name::add(a, b);
    }
}

Це перевіряє, що add не завершується з панікою для широкого діапазону вхідних даних i32.