我正在开发一个Rust库,可以访问某些硬件设备。有两种设备类型,1和2,类型2的功能是类型1功能的超集。
我想为不同的情况提供不同的测试套件:
我正在使用功能来表示此行为:默认功能test-no-device
和可选功能test-type-one
和test-type-two
。然后我使用cfg_attr
属性忽略基于所选功能的测试:
#[test]
#[cfg_attr(not(feature = "test-type-two"), ignore)]
fn test_exclusive() {
// ...
}
#[test]
#[cfg_attr(not(any(feature = "test-type-two", feature = "test-type-one")), ignore)]
fn test_shared() {
// ...
}
这是相当麻烦的,因为我必须为每次测试复制这个条件,并且条件难以阅读和维护。
有没有更简单的方法来管理测试套件?
我在声明模块时尝试设置ignore
属性,但显然只能为每个test
函数设置它。我想我可以通过在模块上使用cfg
禁用编译排除的测试,但由于测试应该总是编译,我想避免这种情况。
答案 0 :(得分:2)
是否有一种简单的方法可以有条件地启用或忽略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() {}
}
}
我必须为每次测试复制此条件,并且条件难以阅读和维护。
这是宏的候选者。
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)
});
类型2的功能是类型1
的功能的超集
在功能定义中反映出来,以简化代码:
[features]
test1 = []
test2 = ["test1"]
如果您这样做,则不需要在配置属性中使用any
或all
。
默认功能
test-no-device
这似乎没用;而是使用正常测试配置保护的正常测试:
#[cfg(test)]
mod test {
#[test]
fn no_device_needed() {}
}
如果您这样做,可以从宏中删除此案例。
我认为如果你遵循这两个建议,你甚至不需要宏。