4 个版本
0.1.3 | 2024年3月3日 |
---|---|
0.1.2 | 2023年11月2日 |
0.1.1 | 2023年10月8日 |
0.1.0 | 2023年6月3日 |
#46 在 测试 中
5,788 每月下载量
在 12 crates 中使用
61KB
781 行
参数化 Rust 测试 & 测试装饰器
test-casing
是一个极简的 Rust 框架,用于生成给定测试用例集的测试,并为它们添加重试、超时、顺序测试处理等装饰。换句话说,该框架实现了
- 对于标准 Rust 测试运行器的低基数参数化测试
- 完全基于代码、可组合和可扩展的测试装饰器。
由于为每个用例生成一个独立的测试包装器,因此它们的数量应该是合理的(大致上,不超过20)。如果用例涉及一些重操作(启动运行时、记录大量信息等),则隔离每个测试用例最有意义。
用法
将其添加到您的 Crate.toml
[dev-dependencies]
test-casing = "0.1.3"
示例:测试用例
use test_casing::{cases, test_casing, TestCases};
use std::error::Error;
#[test_casing(4, [2, 3, 5, 8])]
fn numeric_test(number: i32) {
assert!(number < 10);
}
// Cases can be extracted to a constant for better readability.
const CASES: TestCases<(String, i32)> = cases! {
[2, 3, 5, 8].map(|i| (i.to_string(), i))
};
#[test_casing(4, CASES)]
fn parsing_number(
#[map(ref)] s: &str,
// ^ specifies that argument should be borrowed from `String`
// returned by the `CASES` iterator
expected: i32,
) -> Result<(), Box<dyn Error>> {
assert_eq!(s.parse::<i32>()?, expected);
Ok(())
}
其他功能包括异步测试和 ignore
/ should_panic
属性(后者应用于所有生成的用例)的支持。
use test_casing::test_casing;
#[test_casing(4, [2, 3, 5, 8])]
#[async_std::test]
// ^ test attribute should be specified below the case spec
async fn test_async(number: i32) {
assert!(number < 10);
}
#[test_casing(3, ["not", "a", "number"])]
#[should_panic(expected = "ParseIntError")]
fn parsing_number_errors(s: &str) {
s.parse::<i32>().unwrap();
}
示例:测试装饰器
use test_casing::{
decorate, test_casing, decorators::{Retry, Sequence, Timeout},
};
#[test]
#[decorate(Retry::times(3), Timeout::secs(3))]
fn test_with_retry_and_timeouts() {
// Test logic
}
static SEQUENCE: Sequence = Sequence::new().abort_on_failure();
// Execute all test cases sequentially and abort if one of them fails.
#[test_casing(4, [2, 3, 5, 8])]
#[async_std::test]
#[decorate(&SEQUENCE)]
async fn test_async(number: i32) {
assert!(number < 10);
}
有关使用示例的更多信息,请参阅 crate 文档。
描述性测试用例名称
通过使用 自定义测试框架 API 和一些技巧,如果启用了 nightly
crate 功能,则生成的测试名称将包括提供给目标测试函数的参数值。正如名称所暗示的那样,该功能仅在 nightly Rust 上工作。
以下是此 crate 集成测试输出的摘录,以说明
test cartesian_product::case_6 [number = 5, s = "first"] ... ok
test cartesian_product::case_9 [number = 8, s = "first"] ... ok
test number_can_be_converted_to_string::case_0 [number = 2, expected = "2"] ... ok
test number_can_be_converted_to_string::case_1 [number = 3, expected = "3"] ... ok
test number_can_be_converted_to_string::case_2 [number = 5, expected = "5"] ... ok
test number_can_be_converted_to_string_with_tuple_input::case_0 [(arg 0) = (2, "2")] ... ok
test number_can_be_converted_to_string_with_tuple_input::case_1 [(arg 0) = (3, "3")] ... ok
test number_can_be_converted_to_string_with_tuple_input::case_2 [(arg 0) = (5, "5")] ... ok
test numbers_are_large::case_0 [number = 2] ... ignored, testing that `#[ignore]` attr works
test numbers_are_large::case_1 [number = 3] ... ignored, testing that `#[ignore]` attr works
test string_conversion_fail::case_0 [bogus_str = "not a number"] - should panic ... ok
test string_conversion_fail::case_1 [bogus_str = "-"] - should panic ... ok
test string_conversion_fail::case_2 [bogus_str = ""] - should panic ... ok
test unit_test_detection_works ... ok
参数是测试名称的完整组成部分,这意味着可以将它们包含在测试过滤器中(例如 cargo test 'number = 3'
) 等。
替代品和类似工具
- 从本库中采用的方法可以通过手动输入必要输入到公共参数化测试函数中,进行一定程度的复制粘贴来重现。可选地,这些测试可以收集到一个模块中,以获得更好的结构。这种方法的主要缺点是需要大量的复制粘贴。
- 或者,可以在单个
#[test]
(例如,在循环中)运行多个测试用例。这对于大量的小测试用例(例如,迷你模糊测试)来说是可以的,但可能存在缺点,如日志溢出或重叠以及增加的测试运行时间。 - 名为
test-case
的库采用类似的测试用例结构方法,但在测试用例输入的指定上有所不同。主观上,这个库采用的方法更具可扩展性和易读性。 - 属性测试 / 类似于
quickcheck
的框架提供了更详尽的参数化测试方法,但需要显著更多的设置工作。 rstest
支持测试用例和一些测试装饰器(例如,超时)。nextest
是一个支持该库定义的大多数测试装饰器的替代测试运行器。它不使用基于代码的装饰器配置,也不允许自定义装饰器。使用此库生成的测试可以通过cargo nextest
运行。
许可证
根据您的选择,许可协议为Apache许可证,版本2.0或MIT许可证。
除非您明确声明,否则,根据Apache-2.0许可证定义,您提交给test-casing
的任何有意贡献,将如上所述双重许可,不附加任何额外的条款或条件。
依赖项
~270–730KB
~17K SLoC