4 个版本 (稳定)
| 2.0.0 | 2023年8月27日 | 
|---|---|
| 1.0.1 | 2023年3月9日 | 
| 1.0.0 | 2023年3月8日 | 
| 0.1.0 | 2023年3月8日 | 
#5 在 #ord
每月下载量 30 次
33KB
404 行
Reltester
Relation tester 是一个用于自动检查 [Partial]Eq、[Partial]Ord、Hash 和 [DoubleEnded|Fused]Iterator 特性实现的测试工具。它在与 quickcheck 或其他基于属性的测试框架一起使用时非常有用。
访问 文档!
动机
想象一下,你有一个类型 Foo,它有自定义实现的 PartialEq、Eq、PartialOrd 或 Ord。这里的“自定义”指的是手工编写,而不是继承。Rust 编译器本身无法验证这些实现的正确性,因此必须由你,程序员,来维护关于你所实现的特定 二元关系 的一些不变性。例如,如果你为 Foo 实现 PartialEq,你必须保证 foo1 == foo2 意味着 foo2 == foo1(对称性)。
其他特性如 Hash 和 Iterator 也要求遵守几个不变性——其中一些是非常直观的,而 其他 则不是。在实现 std::iter 系列特性的代码库中,引入不完美的实现是非常常见的,这可能导致诸如 ^1^3 等错误。
想法是,当你手动在代码库中实现这些特性之一时,你可以将这些不变性保存在脑海中,并在测试套件中添加 Reltester 检查,从而有更高的信心保证你的实现是正确的。
如何使用
- 
编写一些测试用例,生成您希望测试的类型随机值。您可以通过手动或使用类似 quickcheck和proptest的 crate 来实现。
- 
根据您的类型实现的特质,调用相应的检查器。 - reltester::eq用于- Eq;
- reltester::ord用于- Ord;
- reltester::partial_eq用于- PartialEq;
- reltester::partial_ord用于- PartialOrd;
- reltester::hash用于- Hash;
- reltester::iterator用于- Iterator;
- reltester::fused_iterator用于- FusedIterator;
- reltester::double_ended_iterator用于- DoubleEndedIterator
 一些这些函数接受多个(两个或三个)相同类型的值。这是因为测试某些不变量可能需要三个值。 
有关更多信息,请参阅文档。如果无法满足主函数的类型界限,则 reltester::invariants 模块可用于更细粒度的检查。
示例
f32(《PartialEq》,PartialOrd;
use reltester;
use quickcheck_macros::quickcheck;
#[quickcheck]
fn test_f32(a: f32, b: f32, c: f32) -> bool {
    // Let's check if `f32` implements `PartialEq` and `PartialOrd` correctly
    // (spoiler: it does).
    reltester::partial_eq(&a, &b, &c).is_ok()
        && reltester::partial_ord(&a, &b, &c).is_ok()
}
u32(《Hash
use reltester;
use quickcheck_macros::quickcheck;
#[quickcheck]
fn test_u32(a: u32, b: u32) -> bool {
    // Unlike `f32`, `u32` implements both `Eq` and `Hash`, which allows us to
    // test `Hash` invariants.
    reltester::hash(&a, &b).is_ok()
}
Vec<u32>(《DoubleEndedIterator
use reltester;
use quickcheck_macros::quickcheck;
#[quickcheck]
fn test_vec_u32(nums: Vec<u32>) -> bool {
    // `Iterator` is implied and checked by both `DoubleEndedIterator` and
    // `FusedIterator`.
    reltester::double_ended_iterator(nums.iter()).is_ok()
        && reltester::fused_iterator(nums.iter()).is_ok()
}
合法
Reltester 在 MIT 许可证下可用。
外部参考和脚注
依赖关系
~0.5–1MB
~23K SLoC