先给结论:不要为每个页面单独截图存档,而要把组件放进“最小页面”和“真实页面”两组样例中,用同一份断言清单分别验证。最小页面用来确认组件自身的样式与脚本边界,真实页面用来确认它被父容器、相邻模块和页面级脚本影响后的结果。两组样例都通过,才算验收成立;只有一组通过,就要先定位差异来源,而不是改样式碰运气。
同一张卡片、同一个轮播或同一组按钮,在列表页正常、在详情页错位,通常不是组件本身随机失效,而是三类条件发生了变化。第一类是布局上下文:父容器的宽度、display、overflow、内边距不同,会让组件的可用宽度和换行位置改变。第二类是页面级脚本:详情页可能引入了额外的初始化逻辑,或对同一选择器绑定了第二次事件。第三类是内容长度:列表页标题只有一行,详情页标题三行,组件内部没有为增长预留空间。
这三类原因需要不同的证据。布局问题在静态截图里就能看到边界溢出;脚本问题往往表现为点击一次触发两次、状态与界面不同步;内容长度问题则只在特定数据下出现。验收样例如果只覆盖“正常内容”,就无法暴露第三类问题。因此构造样例时,先按这三类原因各准备一组输入,比单纯增加页面数量更有效。
常见取舍是“只测组件独立页”还是“只测真实业务页”。两种做法都成立,但适用条件不同。
判断依据可以落在一个动作上:打开组件源码,检查它是否读取了自身根节点之外的 DOM 或全局对象。如果没有,优先独立页;如果有,优先真实页,并把独立页降级为补充样例。这个动作的结果会直接决定下一步——独立页通过而真实页失败时,重点查父容器和页面脚本;两者都失败时,先回到组件内部。
把样例写成可重复执行的三段结构,比记录“看起来正常”更可靠。
假设一个场景:某卡片组件在最小页面宽度 320px 下正常,在详情页同一宽度下右侧被裁掉 8px。断言“根节点宽度不超过父容器”在最小页面通过、在真实页面失败。此时下一步不是调卡片宽度,而是检查详情页父容器是否多了一层内边距或负外边距。若父容器确实多出内边距,修父容器;若父容器正常而卡片自身计算宽度变大,才回到组件内部。这个例子只用于说明比较方法,不代表真实项目数据。
样例不是越多越好。当差异只在某个已废弃页面出现,且该页面不在本次交付范围内,继续为它构造样例会消耗验收时间却不改变交付结果。此时应明确记录“不在范围”,而不是把它当作组件缺陷。反过来,如果差异出现在核心转化路径的页面上,即使只影响一个机型,也应升级为必须覆盖的样例。
还有一种边界:差异由第三方嵌入内容引起,例如外部评论模块或广告位改变了容器高度。此时组件断言仍然有效,但需要在样例中固定第三方区域的高度或明确排除它。不要因为第三方内容变化就判定组件验收失败,也不要在未隔离第三方影响的情况下修改组件样式。
每次运行后,记录三件事:运行位置(最小页面或真实页面)、输入数据类型、失败断言。下次同一组件在别的页面出现异常时,先对照这份记录。如果新页面的失败断言与旧记录相同,说明是可复现的组件边界问题;如果失败断言不同,说明是新页面的上下文引入了新条件。这个动作的价值在于把“感觉不对”变成可比较的条目,让修改范围有依据,而不是每次从截图重新猜起。