Result в тестах
В Rust тестовая функция обычно завершается паникой при неудаче,
однако её можно объявить возвращающей Result.
В этом случае тест считается успешным, если функция возвращает
Ok, и неуспешным - если возвращается Err.
Параметром такой тест не принимает ничего, но его сигнатура
должна явно указывать тип возвращаемого значения, например
Result<(), String> или Result<(), Box<dyn Error>>.
Это удобно, когда вместо assert! хочется использовать
оператор ? и возвращать ошибку без паники.
Синтаксис
#[test]
fn test_name() -> Result<(), E>
{
// test body
Ok(())
}
Пример
Давайте напишем тест, который возвращает
Result<(), String> и проверяет,
что сумма двух чисел равна ожидаемой:
fn add(a: i32, b: i32) -> i32
{
a + b
}
#[test]
fn test_add() -> Result<(), String>
{
let res = add(2, 3);
if res == 5 {
Ok(())
} else {
Err(format!("expected 5, got {}", res))
}
}
fn main()
{
let res = test_add();
println!("{:?}", res);
}
Результат выполнения кода:
Ok(())
Пример
Давайте напишем тест, который вернёт ошибку, если проверяемое условие не выполнено:
fn is_even(n: i32) -> bool
{
n % 2 == 0
}
#[test]
fn test_is_even() -> Result<(), String>
{
let res = is_even(3);
if res {
Ok(())
} else {
Err(String::from("3 is not even"))
}
}
fn main()
{
let res = test_is_even();
println!("{:?}", res);
}
Результат выполнения кода:
Err("3 is not even")
Пример
Давайте используем оператор ? внутри теста
для удобной обработки ошибок:
fn parse_number(s: &str) -> Result<i32, std::num::ParseIntError>
{
s.parse::<i32>()
}
#[test]
fn test_parse() -> Result<(), std::num::ParseIntError>
{
let res = parse_number("12345")?;
if res == 12345 {
Ok(())
} else {
Ok(())
}
}
fn main()
{
let res = test_parse();
println!("{:?}", res);
}
Результат выполнения кода:
Ok(())
Смотрите также
-
атрибут
test,
который помечает функцию как тестовую -
макрос
assert!,
который проверяет истинность условия -
макрос
panic!,
который немедленно завершает тест с ошибкой -
атрибут
should_panic,
который проверяет, что тест вызывает панику