Тестування документації
Основний спосіб документування проєкту Rust — це анотування вихідного коду. Коментарі документації пишуться за специфікацією CommonMark Markdown і підтримують у собі блоки коду. Rust дбає про коректність, тож ці блоки коду компілюються і використовуються як тести документації.
/// Перший рядок — це короткий підсумок, який описує функцію.
///
/// Наступні рядки містять докладну документацію. Блоки коду починаються з
/// потрійних зворотних лапок і мають неявний `fn main()` всередині
/// та `extern crate <cratename>`. Припустімо, що ми тестуємо крейт `playground`
/// або використовуємо дію Test у Playground:
///
/// ```
/// let result = playground::add(2, 3);
/// assert_eq!(result, 5);
/// ```
pub fn add(a: i32, b: i32) -> i32 {
a + b
}
/// Зазвичай doc-коментарі можуть містити розділи "Examples", "Panics" і "Failures".
///
/// Наступна функція ділить два числа.
///
/// # Examples
///
/// ```
/// let result = playground::div(10, 2);
/// assert_eq!(result, 5);
/// ```
///
/// # Panics
///
/// Функція panic, якщо другий аргумент дорівнює нулю.
///
/// ```rust,should_panic
/// // panic при діленні на нуль
/// playground::div(10, 0);
/// ```
pub fn div(a: i32, b: i32) -> i32 {
if b == 0 {
panic!("Divide-by-zero error");
}
a / b
}
Блоки коду в документації автоматично тестуються
під час запуску звичайної команди cargo test:
$ cargo test
running 0 tests
test result: ok. 0 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Doc-tests playground
running 3 tests
test src/lib.rs - add (line 7) ... ok
test src/lib.rs - div (line 21) ... ok
test src/lib.rs - div (line 31) ... ok
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
Мотивація, що стоїть за тестами документації
Основна мета тестів документації — слугувати прикладами, які перевіряють
функціональність, що є одним із найважливіших
настанов. Це дає змогу використовувати приклади з
документації як повноцінні фрагменти коду. Але використання ? призводить до
помилки компіляції, оскільки main повертає unit. Тут у пригоді стає
можливість приховувати деякі рядки вихідного коду від документації: можна
написати fn try_main() -> Result<(), ErrorType>, приховати його
і unwrap-нути в прихованому main. Звучить складно? Ось приклад:
/// Використання прихованого `try_main` у doc-тестах.
///
/// ```
/// # // приховані рядки починаються зі символу `#`, але вони все одно компілюються!
/// # fn try_main() -> Result<(), String> { // рядок, що обгортає тіло, показане в doc
/// let res = playground::try_div(10, 2)?;
/// # Ok(()) // повернення з try_main
/// # }
/// # fn main() { // початок main, який буде робити unwrap()
/// # try_main().unwrap(); // виклик try_main і розгортання
/// # // так, щоб тест panic у разі помилки
/// # }
/// ```
pub fn try_div(a: i32, b: i32) -> Result<i32, String> {
if b == 0 {
Err(String::from("Divide-by-zero"))
} else {
Ok(a / b)
}
}
Див. також
- RFC505 щодо стилю документації
- API Guidelines щодо настанов з документації