10 个版本
使用旧的 Rust 2015
0.2.3 | 2019年9月30日 |
---|---|
0.2.2 | 2019年9月30日 |
0.2.1 | 2018年9月19日 |
0.2.0 | 2018年5月11日 |
0.1.4 | 2017年8月31日 |
#89 in #test-cases
每月 55 次下载
在 2 crate 中使用
28KB
292 行
此 crate 已废弃。请使用 test-case 代替
Test-case-derive 存在一些问题,由于时间不足,我无法解决。幸运的是,@frondeus 分支了它并解决了所有问题。最重要的区别
- 名称不再包含误导性的
derive
。当我创建这个 crate 时,我没有足够了解进程宏,并添加了这个不幸的后缀,没有任何实际原因 - 它使用更新的 syn,并且不再直接在标记上工作
- 语法略有变化,
::
不再使用。相反,;
现在用于分隔测试用例名称 - 可以为您的测试用例添加属性,例如
#[should_panic]
或#[ignore]
概述
此 crate 提供 #[test_case]
进程宏属性,该属性使用单个体和不同的输入参数生成多个参数化测试。对于每个传递给 test_case
属性的数据集生成一个测试。在底层,具有相同体的所有测试用例都被分组到 mod
中,从而给出清晰且易于阅读的测试结果。
入门指南
首先,您必须将此依赖项添加到您的 Cargo.toml
[dev-dependencies]
test-case-derive = "0.2.0"
此外,您必须启用 proc_macro
功能并包含 crate。您可以通过添加以下内容全局完成此操作:
#![feature(proc_macro)]
extern crate test_case_derive;
请将以下命令添加到您的 lib.rs
或 main.rs
文件中。可选地,您可以为测试仅启用 proc macros。
#![cfg_attr(test, feature(proc_macro))]
#[cfg(test)]
extern crate test_case_derive;
请记住,过程宏是通过 use
语句导入的。
use test_case_derive::test_case;
示例用法
#![cfg(test)]
#![feature(proc_macro)]
extern crate test_case_derive;
use test_case_derive::test_case;
#[test_case( 2, 4 :: "when both operands are possitive")]
#[test_case( 4, 2 :: "when operands are swapped")]
#[test_case(-2, -4 :: "when both operands are negative")]
fn multiplication_tests(x: i8, y: i8) {
let actual = (x * y).abs();
assert_eq!(8, actual)
}
此示例的输出来自 cargo test
$ cargo test
running 3 tests
test multiplication_tests::when_both_operands_are_possitive ... ok
test multiplication_tests::when_both_operands_are_negative ... ok
test multiplication_tests::when_operands_are_swapped ... ok
test result: ok. 3 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out
示例
如果您的唯一断言只是 assert_eq!
,您可以使用 =>
语法将期望作为宏属性传递。
#[test_case( 2 => 2 :: "returns given number for positive input")]
#[test_case(-2 => 2 :: "returns opposite number for non-positive input")]
#[test_case( 0 => 0 :: "returns 0 for 0")]
fn abs_tests(x: i8) -> i8 {
if x > 0 { x } else { -x }
}
这相当于
#[test_case( 2, 2 :: "returns given number for positive input")]
#[test_case(-2, 2 :: "returns opposite number for non-positive input")]
#[test_case( 0, 0 :: "returns 0 for 0")]
fn abs_tests(x: i8, expected: i8){
let actual = if x > 0 { x } else { -x };
assert_eq!(expected, actual);
}
属性和期望可以是任何表达式,除非它们包含 =>
,例如。
#[test_case(None, None => 0 :: "treats none as 0")]
#[test_case(Some(2), Some(3) => 5)]
#[test_case(Some(2 + 3), Some(4) => 2 + 3 + 4)]
fn fancy_addition(x: Option<i8>, y: Option<i8>) -> i8 {
x.unwrap_or(0) + y.unwrap_or(0)
}
注意:实际上,=>
并未被禁止,但解析器总是将最后一个 =>
符号视为期望定义的开始。
测试用例名称是可选的。它们通过在宏属性末尾使用 ::
后跟字符串字面量来设置。
示例生成的代码
mod fancy_addition {
#[allow(unused_imports)]
use super::*;
fn fancy_addition(x: Option<i8>, y: Option<i8>) -> i8 {
x.unwrap_or(0) + y.unwrap_or(0)
}
#[test]
fn treats_none_as_0() {
let expected = 0;
let actual = fancy_addition(None, None);
assert_eq!(expected, actual);
}
#[test]
fn some_2_some_3() {
let expected = 5;
let actual = fancy_addition(Some(2), Some(3));
assert_eq!(expected, actual);
}
#[test]
fn some_2_3_some_4() {
let expected = 2 + 3 + 4;
let actual = fancy_addition(Some(2 + 3), Some(4));
assert_eq!(expected, actual);
}
}
不确定的(被忽略的)测试用例(自 0.2.0 版起)
如果测试用例名称(使用上述 ::
语法传递)包含单词 "inconclusive",则生成的测试将标记为 #[ignore]
。
#[test_case("42")]
#[test_case("XX" :: "inconclusive - parsing letters temporarily doesn't work but it's ok")]
fn parses_input(input: &str) {
// ...
}
生成的代码
mod parses_input {
// ...
#[test]
pub fn _42() {
// ...
}
#[test]
#[ignore]
pub fn inconclusive_parsing_letters_temporarily_doesn_t_work_but_it_s_ok() {
// ...
}
注意:单词 inconclusive
仅在 ::
后的测试名称中保留。
贡献
欢迎所有贡献和评论!如果您发现错误或有改进此 crate 的想法,请不要害怕打开问题或 PR。
许可证
MIT 许可证
版权所有 (c) 2017 Marcin Sas-Szymański
在此条件下,任何人未经许可均可免费获得此软件及其相关文档副本(“软件”),包括但不限于使用、复制、修改、合并、发布、分发、再许可和/或出售软件副本,并允许向软件提供方提供软件的人执行上述操作:以下条件
上述版权声明和本许可声明应包含在软件的所有副本或主要部分中。
软件按“原样”提供,不提供任何明示或暗示的保证,包括但不限于适销性、适用于特定目的和无侵权性保证。在任何情况下,作者或版权所有者均不对任何索赔、损害或其他责任负责,无论此类索赔、损害或其他责任是由于合同、侵权或其他方式引起的,与软件或软件的使用或其他交易有关。
依赖项
~1.5MB
~41K SLoC