响应式界面:用关键状态做视觉回归

跨端一致不是每一像素都相同。更重要的是内容层级、阅读顺序和操作反馈在不同宽度下仍然成立。先选典型的窄屏、常用桌面宽度和容器受限场景,再为它们准备稳定的页面状态。

先固定会制造噪声的东西

视觉测试应固定字体、语言、时区、动画和数据。否则截图差异常来自日期、头像或网络结果,而不是布局问题。颜色和阴影可以有少量容差;按钮被截断、焦点丢失、正文溢出则应该直接失败。

await page.emulateMedia({ reducedMotion: 'reduce' });
await expect(page.getByTestId('product-grid')).toHaveScreenshot('grid-narrow.png');

规则放在组件旁边

容器查询适合由容器宽度决定的卡片,视口媒体查询适合页面级变化。动态视口单位需要准备旧环境的回退,不要只看一种浏览器。每次出现新断点,先确认是不是组件结构可以解决;断点堆得越多,维护成本越高。

差异图只是线索,合并前仍要看实际交互。截图过了,不代表键盘操作和长文本一定正确。

状态选择比截图数量重要

每个页面不需要为所有排列组合截屏,但要覆盖最容易改变结构的状态。商品列表至少要有空结果、加载骨架、长标题和筛选项很多的情况;表单则要有校验错误、禁用提交和键盘聚焦。把这些状态做成固定的测试数据,截图才不会跟着接口内容漂移。遇到线上问题时,也可以把最小数据补进状态库,避免同一类错误反复手工复现。

窄屏测试别只用一台常见手机的宽度。侧边栏收起、卡片从两列变一列、操作按钮换行,这些变化往往发生在相邻的几个像素范围内。对关键断点前后各取一个宽度,能更早发现突然跳动或内容被遮挡。容器查询组件还要放进不同父容器里测,因为它的行为并不由整页视口决定。

把可访问性一起回归

视觉基线稳定后,再确认 Tab 顺序、焦点样式和读屏名称。响应式改造最常见的失误,是视觉上把操作移动到另一行,却把 DOM 顺序和阅读顺序留在原处。使用键盘打开菜单、关闭弹窗、提交表单,能很快发现这类问题。对于横向滚动区域,还要验证焦点元素会自动进入可见范围。

当截图出现差异,先看是否由字体渲染、抗锯齿或平台阴影造成,再判断是否需要更新基线。不要为了消除噪声把阈值调得太宽,否则真正的文本截断也会被放过去。测试的职责是把变化缩小到可判断的范围,最终是否符合产品意图仍需要人来确认。

基线图片也要跟版本一起维护。组件外观确实调整时,先在评审中说明影响的宽度和状态,再有选择地更新对应截图;不要一次性重录全部图片来掩盖未知变化。对于平台渲染差异,可以按浏览器分别维护少量基线,但避免让测试矩阵膨胀到没人愿意看。视觉回归的价值不在于截图越多越好,而在于每张图都对应一个明确、长期会出问题的界面约束。

页面更新后也应保留一次人工浏览。自动化能发现偏移,却很难判断信息层级是否仍然自然、按钮是否还足够醒目。

把发现的问题按组件归档,而不是只写在某个页面的截图旁。相同卡片在别处复用时,修复才能同步生效,测试基线也更容易维护。

Logo

一站式 AI 云服务平台

更多推荐