先把“表现不同”拆成可观察的差异:是数据不同、容器不同,还是交互状态不同。构造验收样例时,不要只截一张出问题的页面,而要为同一组件准备两组对照页面,一组保持原样,一组只改一个条件,然后记录组件在两组中的实际输出。这样做的目的是把“我觉得它坏了”变成“在A条件下它输出X,在B条件下它输出Y”,让开发、设计、内容三方都能核对同一个事实。
同一组件在不同页面表现不同,最常见的原因有两类。第一类是传入组件的数据结构不同,比如列表页传的是摘要字段,详情页传的是完整字段,组件对空值或长文本的处理就会分叉。第二类是组件所处的容器不同,比如父级宽度、栅格列数、是否处于弹窗或折叠区域,都会改变它的换行、截断和点击区域。
判断依据可以这样取:把同一份数据分别放进两个页面,如果表现仍然不同,问题更可能在容器或样式作用域;如果把两个页面的数据互换后表现跟着数据走,问题更可能在数据契约。这个判断不需要工具,只需要做一次替换动作。动作的结果决定下一步:数据问题就回到接口字段和默认值,容器问题就回到布局约束和样式覆盖。
条件一:组件在多个页面复用,且各页面数据来源一致。这时验收样例应以容器为变量。为同一组件准备窄容器和宽容器两个页面,分别放入等长的短文本、中等文本和超长文本,记录换行位置、是否出现横向滚动、按钮是否仍可点击。样例通过的条件不是“看起来正常”,而是三个文本长度下组件边界都不溢出,且交互元素的可点击区域没有被遮挡。
条件二:组件在多个页面复用,但各页面数据来源不同。这时验收样例应以数据为变量。固定同一个容器,分别传入缺字段、字段为空字符串、字段超长三种输入,记录组件是否显示占位、是否报错、是否把空值渲染成“undefined”。样例通过的条件是三种输入都有明确降级表现,而不是只在完整数据下正常。
两种选择的分界点在于:如果差异只在某个页面出现,先查该页面的数据;如果差异在多个页面随机出现,先查容器和样式作用域。例外是组件内部带有异步请求时,数据与容器会互相掩盖,此时应先把请求结果固定为静态数据,再分别验证容器和数据,否则验收样例会同时受网络和布局影响,无法定位。
当设计、开发、内容对同一组件有不同理解时,不要继续争论“应该是什么样”,而是把分歧写成一张对照表。每一行只写一个条件、一个预期、一个实际。例如:
这张表的作用是让每个角色只对自己能判断的列负责:内容确认预期文案,设计确认截断和换行,开发确认实际输出。核对完成后,把通过的条件固化成验收样例,把未通过的条件转成待修项。下一步动作是:先修影响面最大的条件,再回归另外两组条件,避免修好一个页面又破坏另一个页面。
假设某站点有一个“文章卡片”组件,在列表页显示正常,在搜索结果页显示异常。先不修改代码,而是复制搜索结果页的卡片,替换成列表页的同一份数据。如果异常消失,说明问题在搜索结果页传入的数据;如果异常仍在,说明问题在搜索结果页的容器或样式。这个替换动作只需要几分钟,却能避免直接改组件导致列表页也受影响。得到结果后,下一步只改被定位的那一侧,并重新跑一遍两组对照样例。
可核对的样例至少包含:页面地址或页面标识、传入数据的样子、容器宽度或布局位置、操作步骤、预期输出、实际输出。缺少其中任何一项,不同角色就会再次产生不同理解。还要注意,页面请求量或抓取量归零不能单独证明组件处理正确,它可能只是页面未被访问、缓存未更新或统计口径变化,必须回到对照样例本身核对输出。
最后,把通过的条件写成可重复执行的检查项,而不是一次性的截图。这样下次同一组件在新页面复用时,可以直接套用已有样例,先判断它属于数据差异还是容器差异,再决定改哪一侧。验收样例的价值不在于证明某个页面没问题,而在于让下一次分歧出现时,团队能快速回到同一组可核对的事实上。