consistency 教程
本页面向贡献者:介绍如何运行跨包一致性测试,以及在向 immut 和 mutable 同时添加某个运算时如何添加测试。其中的道理见 consistency 设计。
快速上手
在仓库根目录下:
moon test -p consistency
所有测试都在默认目标上运行;该包没有目标专用代码。
日常任务
添加一致性测试
在两个包中构造相同的输入,应用该运算,再比较共同的观察结果。这类测试的形式如下,就像它出现在 src/consistency/core_wbtest.mbt 中那样:
///|
test "anti_trace stays aligned" {
let imm = @immut.Matrix::from_2d_array([[1, 2], [3, 4]])
let mut_m = @mutable.Matrix::from_2d_array([[1, 2], [3, 4]])
inspect(
imm.anti_trace().unwrap(),
content=mut_m.anti_trace().unwrap().to_string(),
)
}
以性质的形式添加定律
使用 quick_check_fn 配合由小整数组成的元组,返回一个 Bool,在两个包中比较定律两边。使用整数可以保持比较精确。
同样的思路也适用于你自己的代码。下面这个随手册一起编译的检查,在一个乘积上比较两个包:
///|
test "products agree across packages" {
let rows = [[1, -2], [3, 4]]
let i = @immut.Matrix::from_2d_array(rows)
let m = @mutable.Matrix::from_2d_array(rows)
debug_inspect((i * i).to_array() == (m * m).to_array(), content="true")
}
进一步了解
当某个运算在两个包之间有意不同时,请添加一个说明该差异的测试,并在两个 API 页面中注明。
常见陷阱
- 用
==比较Double结果。 各内核的求和顺序不同;一致性测试请保持使用整数。 - 跨元素类型比较
to_string。 当打印形式可能只在格式上不同时,请使用to_array。
后续步骤
- consistency API:测试列表。
- immut API 和 mutable API。