Атрибут cfg(not(test))
Атрибут cfg(not(test)) является условным атрибутом компиляции, который сообщает компилятору Rust о необходимости включить помеченный код только тогда, когда тестирование не выполняется. Иными словами, код, помеченный этим атрибутом, будет скомпилирован при обычной сборке проекта, но будет полностью исключён при запуске команды cargo test. Это особенно полезно, когда необходимо иметь разное поведение программы в режиме тестирования и в обычном режиме работы, например, для подмены функций ввода-вывода или отключения дорогостоящих операций.
Синтаксис
#[cfg(not(test))]
fn function_name()
{
// код, который не компилируется при тестах
}
Пример
Давайте рассмотрим простой пример, в котором функция main и вспомогательная функция помечены атрибутом cfg(not(test)), чтобы они не участвовали в компиляции при запуске тестов:
#[cfg(not(test))]
fn main()
{
let res = calculate(2, 3);
println!("{}", res);
}
#[cfg(not(test))]
fn calculate(a: i32, b: i32) -> i32
{
a + b
}
#[cfg(test)]
mod tests
{
use super::*;
#[test]
fn test_calculate()
{
assert_eq!(calculate(2, 3), 5);
}
}
При обычной сборке и запуске программы будет выведено число 5. Однако при выполнении команды cargo test функция main и функция calculate будут исключены из компиляции, и тест не сможет обратиться к calculate, что вызовет ошибку компиляции. Поэтому на практике атрибут cfg(not(test)) чаще применяют к коду, который не должен использоваться в тестах, но не является обязательным для тестируемых функций.
Пример
Более корректный пример: пометим атрибутом cfg(not(test)) только функцию main, а вспомогательную функцию оставим доступной для тестов:
#[cfg(not(test))]
fn main()
{
let res = calculate(2, 3);
println!("{}", res);
}
fn calculate(a: i32, b: i32) -> i32
{
a + b
}
#[cfg(test)]
mod tests
{
use super::*;
#[test]
fn test_calculate()
{
assert_eq!(calculate(2, 3), 5);
}
}
Результат выполнения обычной программы:
5
Результат выполнения команды cargo test:
running 1 test
test tests::test_calculate ... ok
test result: ok. 1 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out