概念定义
有些系统天生击败“期望值”这个概念:推荐系统该返回什么?蜕变测试绕开预言,改测输出如何协同变化——在相关输入之间,关系本身就是规约。
工作机制
定义扎根领域语义的关系:向购物车加项不得使总额下降;输入重排后集合型输出相等;单位缩放在容差内线性缩放输出。生成基础输入、按关系变换派生后续输入、两者都执行、断言关系成立。
使用场景
ML 模型行为漂移检查、编译器优化正确性、排序一致性、定价引擎、地理与数值管线。与性质测试生成器天然配对——由它产出输入对。
常见误区
关系强度决定检出力:弱关系在坏代码上照样通过、白跑一趟。“只适用于数值代码”是误解——排序、搜索、ML 领域用它恰恰因为那里没有预言。未声明容差的关系配上浮点噪声就是 flaky;零、负数、空集等域边界可以合法地违反朴素关系——定义必须圈定适用域;在关系从未定义的非法输入域上套用则是自找误报。
代码示例
export interface PropertyCase { readonly numbers: number[]; }
export function check(numbers: number[]): boolean {
return numbers.every((n, i) => i === 0 || (numbers[i - 1] as number) <= n);
}
export function shrink(failing: number[], holds: (input: number[]) => boolean): number[] {
let current = failing;
let changed = true;
while (changed) {
changed = false;
for (let i = 0; i < current.length; i++) {
const candidate = current.filter((_, index) => index !== i);
if (!holds(candidate)) {
current = candidate;
changed = true;
break;
}
}
}
return current;
}
export function findCounterexample(seed: number[], holds: (input: number[]) => boolean): number[] | null {
if (!holds(seed)) return shrink(seed, holds);
return null;
}