unit-testing - 有没有一种简单的方法可以有条件地启用或忽略 Rust 中的整个测试套件?
问题描述
我正在开发一个提供对某些硬件设备的访问的 Rust 库。有两种设备类型,1 和 2,类型 2 的功能是类型 1 功能的超集。
我想针对不同的情况提供不同的测试套件:
- 没有连接设备的测试(基本的健全性检查,例如 CI 服务器)
- 测试共享功能(需要类型 1 或 2 的设备)
- 测试类型 2 的专有功能(需要类型 2 的设备)
我正在使用特性来表示这种行为:默认特性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
编译,但由于测试应该始终编译,我想避免这种情况。
解决方案
有没有一种简单的方法可以有条件地启用或忽略 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() {}
}
}
我必须为每个测试复制这个条件,而且这些条件很难阅读和维护。
- 你能用纯 Rust 表示所需的功能吗?是的
- 现有的语法是否过于冗长?是的
这是宏的候选对象。
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() {}
}
如果你遵循这个,你可以从宏中删除这个案例。
我认为如果您遵循这两个建议,您甚至不需要宏。
推荐阅读
- node.js - AWS @aws-sdk/lib-dynamodb '无法读取未定义的属性'0''
- python - 不使用 BuildKit 时 Docker 'Permission denied'
- java - 如何使用 WindowEvent 终止这个示例 Swing 应用程序?
- python - 我有这些词典。我应该使用什么命令来打印第二个中的“d”键?有个窍门
- reactjs - 如何在 React js 上删除满足特定条件的列表元素
- testing - 是否可以在 testcafe-browser-provider-saucelabs 中添加 iPad 参数“deviceOrientation”?
- c# - 如何以编程方式从动态 JObject 中删除属性
- c# - 实体框架 - SaveChanges 与事务
- php - 如何过滤 wordpress the_date() 和 get_the_date() 函数以仅显示帖子发布的年份
- .net-core - Abp中如何使用EfCore Code First将实体中的注解生成到数据库的字段描述中