内容提要
遗留系统迁移最危险的时刻是新实现看似完成、准备切流之时。差异测试通过用相同输入运行新旧实现并比较输出,发现行为差异。需规范化时间戳等无关差异,比较错误与副作用,分类每处差异,并用影子流量验证。差异测试将迁移风险转化为可衡量证据,但不能证明新行为正确,最终仍需业务判断。
延伸解读
差异测试的适用边界
差异测试通过比较新旧实现的行为差异来暴露迁移风险,但它并非万能。文章明确指出,差异测试只能回答“行为是否改变”,不能回答“新行为是否正确”。如果遗留系统本身存在缺陷,新实现复制了同样的错误,差异测试会通过,但错误依然存在。因此,差异测试必须与规格测试、业务需求、领域评审等互补使用,不能作为正确性的唯一证据。
影子流量的安全前提
影子流量能在生产环境用真实请求对比新旧实现,发现测试用例未覆盖的边界情况。但文章强调,对于有副作用的操作(如支付、发货、发邮件),必须用记录适配器替代真实调用,避免重复执行破坏性操作。影子执行应只比较行为意图,而不是复制生产效果。此外,生产数据需匿名化,防止敏感信息泄露。
差异分类与决策分离
差异测试会发现大量不匹配,但每个差异不一定都是缺陷。文章建议将差异分类为迁移缺陷、有意保留的遗留缺陷、有意行为变更、表示差异、非确定性差异、比较器缺陷或未知。分类后,是否接受变更需要业务判断,而不是由测试或AI决定。AI可用于定位差异原因,但不应裁决哪种行为正确。
量化分歧而非追求完美
迁移中追求零差异不现实。文章提出用分歧率衡量:比较10万次请求,99,620次等价,380次不同,其中250次时间戳差异、80次已知有意变更、30次比较器问题、15次已修复缺陷、5次未解释。归一化后,有意义未解决分歧仅0.005%。但百分比不是唯一标准,一个错误的金融交易可能比100个无害格式差异更严重,需结合严重性评估。
Q&A
什么是差异测试?它在遗留系统迁移中起什么作用?
差异测试是一种通过用相同输入运行新旧实现并比较输出,来发现行为差异的方法。在遗留系统迁移中,它帮助将迁移风险转化为可衡量的证据,但不能证明新行为正确,最终仍需业务判断。
在差异测试中,如何处理时间戳和随机ID等非确定性值?
可以通过依赖控制,将非确定性源(如时钟、ID生成器)抽象为接口,在测试中注入固定值,使两个实现获得相同值。如果无法控制,则可以在规范化时移除这些值,但前提是它们不属于需要保护的行为。
差异测试中如何比较错误和副作用?
错误应作为契约的一部分进行比较,例如比较错误类型、HTTP状态码、错误码等,而不是精确措辞。副作用可以通过记录适配器捕获,比如记录支付调用或事件发布,然后比较新旧实现产生的副作用列表是否一致。
如何安全地使用影子流量进行差异测试?
影子流量将真实请求复制到新系统,但用户仍收到旧系统的响应。必须防止影子执行产生重复副作用,例如用记录适配器替代真实支付网关,只记录意图而不执行真实操作。同时要处理隐私风险。
差异测试能否证明新系统行为正确?
不能。差异测试只能比较新旧实现的行为差异,但旧系统本身可能有错误。如果旧系统输出错误,新系统输出相同错误,测试会通过,但这并不代表行为正确。因此差异测试需要与规格测试、业务需求等互补。
在差异测试中,如何对发现的差异进行分类?
差异可以分为迁移缺陷、有意保留的旧缺陷、有意的行为变更、表示差异、非确定性差异、测试/比较器缺陷以及未知类别。分类有助于决定哪些差异需要修复,哪些可以接受。