[在基于属性的测试设置中,例如Haskell对自定义数据结构的快速检查,如何为关系的n元属性(例如,传递性或对称性)生成测试数据?我认为实现语言无关紧要。
这是一个使用rapidcheck的天真的C ++示例(只是因为我现在手头有此工具):
rc::check("Double equality is symmetric.", [](double a, double b) {
RC_ASSERT(!(a == b) || (b == a)); // a == b ==> b == a
});
在这种幼稚的情况下,该工具不太可能在前提(a == b
)实际存在的情况下生成许多示例,因此您最终在无意义的测试上浪费了很多精力。对于三元关系(如传递性),情况甚至更糟。
是否有解决这些问题的通用技术?我是否需要生成相等对(对于“相等”的一些建设性定义)?订单之类的东西呢?
提高值冲突可能性的方法是将值生成限制在较小的范围内,有时将其与更通用的生成器结合使用。
考虑以下从https://johanneslink.net/how-to-specify-it/#46-a-note-on-generation改编的生成器:
@Provide
Arbitrary<Integer> keys() {
return Arbitraries.oneOf(
Arbitraries.integers().between(-25, 25),
Arbitraries.integers()
);
}
生成将首先以相等的概率在任意整数和-25与+25之间的整数之间进行选择。因此,大约每100个值将重复一次。
在更困难的情况下,我什至可能会有一个生成器,它从一小组预定义值中进行选择。