gpt4 book ai didi

testing - Rust:带有 lib 和二进制目标的 crate 中的属性 #[cfg(test)]

转载 作者:行者123 更新时间:2023-12-03 08:17:38 25 4
gpt4 key购买 nike

我目前正在开发 Rust project它有一个库目标和一个二进制目标。

该库定义了两种 panic 处理程序,一种用于生产使用,一种用于测试,它们使用 #[cfg(test)] 属性进行条件编译。这对于单元测试 src/lib.rs 来说效果很好,但是一旦在 test/(或 src/main.rs )中进行集成测试,“生产” panic 处理程序就会被链接进来,即在这些情况下,lib. rs 使用 test=false 进行编译。

有什么方法可以防止/配置这种情况吗?

使用以下目录结构可以最低程度地重现这一点:

Cargo.toml
src/lib.rs
src/main.rs

list 如下所示:

# Cargo.toml
...
[lib]
name = "kernel"

[[bin]]
path = "src/main.rs"
name = "titanium"

二进制代码:

// main.rs

fn main() {
println!("Hello, world!");
}

#[test]
fn it_works() {
assert_eq!(kernel::hello(), "Hello!".to_string());
}

...对于图书馆:

// lib.rs

#[cfg(test)]
pub fn hello() -> String {
"Hello!".to_string()
}

#[cfg(not(test))]
pub fn hello() -> String {
"Goodbye!".to_string()
}

#[test]
fn it_works() {
assert_eq!(hello(), "Hello!".to_string())
}

回答事实上,上述行为对于大约 99% 的用例来说都是可取的,但是,我的用例不是其中之一。

对于我的用例(在“ headless ”虚拟机中运行的玩具操作系统的测试套件,即仅输出到主机的标准输出),我最终定义了一个功能来切换 panic 处理程序。适应上面的例子,现在看起来像这样:

# Cargo.toml
...
[features]
test_qemu_headless = []

二进制文件保持不变,并且在库中我这样做

// lib.rs

#[cfg(feature = "test_qemu_headless")]
pub fn hello() -> String {
"Hello!".to_string()
}

#[cfg(not(feature = "test_qemu_headless"))]
pub fn hello() -> String {
"Goodbye!".to_string()
}

#[test]
fn it_works() {
assert_eq!(hello(), "Hello!".to_string())
}

然后运行测试

cargo test --features test_qemu_headless

最佳答案

lib 目标被编译两次:一次是在运行单元测试时;一次是在运行单元测试时;一次是在运行单元测试时。在这里,#[cfg(test)]处于事件状态,因为该库当前正在编译为 rustc --test 。第二次运行集成测试时;在这里,#[cfg(test)] 处于事件状态,因为该库正在正常编译,然后链接到集成测试模块,这些模块本身被编译为测试。换句话说,当与集成测试一起使用时,lib 目标不知道它正在被编译并在测试中使用(这在某种程度上是集成测试的重点)。

您正在寻找的是 #[cfg(debug_assertions)] 来装饰你的 panic 处理程序。无论出于何种原因,只要代码在“调试”模式下编译,此属性就会处于事件状态。使用此属性,您的测试处理程序将对单元测试和集成测试都有效。

但是,如果您在“调试”模式下编译 bin 目标并运行它(例如通过 cargo run 而不使用 --release ),或者如果您的库被在“调试”模式下编译的其他一些 crate 所依赖,库中的测试处理程序也将处于事件状态,这可能不是您想要的。如果是这样,您需要定义 feature对于您的 crate ,依赖于您的 panic 处理程序的测试可以将其用作条件编译的标志(例如 foocrate_use_internal_dummy_panic_handler )。然后,您需要在运行测试时激活该功能 - 这将成为全局旋钮。还有一个 required-feature - list 中的字段。

关于testing - Rust:带有 lib 和二进制目标的 crate 中的属性 #[cfg(test)],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68876553/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com