I\xe2\x80\x99m 正在开发一个 Rust 库,该库提供对某些硬件设备的访问。有两种设备类型:1 和 2,类型 2 的功能是类型 1 功能的超集。
\n\n我想针对不同的情况提供不同的测试套件:
\n\nI\xe2\x80\x99m 使用功能来表示此行为:默认功能test-no-device
和可选功能test-type-one
以及test-type-two
. 然后我使用该cfg_attr
属性来忽略基于所选功能的测试:
#[test]\n#[cfg_attr(not(feature = "test-type-two"), ignore)]\nfn test_exclusive() {\n // ...\n}\n\n#[test]\n#[cfg_attr(not(any(feature = "test-type-two", feature = "test-type-one")), ignore)]\nfn test_shared() {\n // ...\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n这是相当麻烦的,因为我必须为每个测试复制这个条件,并且这些条件很难阅读和维护。
\n\n有没有更简单的方法来管理测试套件?
\n\n我尝试ignore
在声明模块时设置该属性,但显然只能为每个test
函数设置该属性。我认为我可以通过cfg
在模块上使用来禁用排除测试的编译,但由于测试应该始终编译,我想避免这种情况。
有没有一种简单的方法可以有条件地启用或忽略 Rust 中的整个测试套件?
最简单的是甚至不编译测试:
#[cfg(test)]
mod test {
#[test]
fn no_device_needed() {}
#[cfg(feature = "test1")]
mod test1 {
fn device_one_needed() {}
}
#[cfg(feature = "test2")]
mod test2 {
fn device_two_needed() {}
}
}
Run Code Online (Sandbox Code Playgroud)
我必须为每个测试重复这个条件,并且这些条件很难阅读和维护。
这是宏的候选者。
macro_rules! device_test {
(no-device, $name:ident, {$($body:tt)+}) => (
#[test]
fn $name() {
$($body)+
}
);
(device1, $name:ident, {$($body:tt)+}) => (
#[test]
#[cfg_attr(not(feature = "test-type-one"), ignore)]
fn $name() {
$($body)+
}
);
(device2, $name:ident, {$($body:tt)+}) => (
#[test]
#[cfg_attr(not(feature = "test-type-two"), ignore)]
fn $name() {
$($body)+
}
);
}
device_test!(no-device, one, {
assert_eq!(2, 1+1)
});
device_test!(device1, two, {
assert_eq!(3, 1+1)
});
Run Code Online (Sandbox Code Playgroud)
类型 2 的功能是类型 1 功能的超集
在您的功能定义中反映这一点以简化代码:
[features]
test1 = []
test2 = ["test1"]
Run Code Online (Sandbox Code Playgroud)
如果您这样做,则不需要在配置属性中包含any
或。all
默认功能
test-no-device
这似乎没什么用;相反,使用由正常测试配置保护的正常测试:
#[cfg(test)]
mod test {
#[test]
fn no_device_needed() {}
}
Run Code Online (Sandbox Code Playgroud)
如果您遵循此操作,则可以从宏中删除这种情况。
我认为如果您遵循这两个建议,您甚至不需要宏。
归档时间: |
|
查看次数: |
2049 次 |
最近记录: |