能真正压测 UI 的 mock 数据(而不是只把页面填满)
Mock 数据的意义不是把屏幕填满,而是让渲染屏幕的代码得到锻炼。十行除 id 外完全相同的行,测不到空状态、长名字、缺失字段和 null 日期,而这些恰恰是格式化 bug 真正藏身的地方。好的 mock 数据长得很像真实数据,并默认带上会破坏你代码的边界情况。
Mock 数据是后端还在建时,你发给前端占位用的东西。这个占位的质量,决定了哪些 bug 在后端出现之前被发现,哪些要等到上线后才暴露。大多数 mock 数据坏在一种具体且可预测的方式上:太单一。十行同名只是 id 不同,填满了页面,却几乎没锻炼到任何渲染代码。
为什么单一的 mock 数据会掩盖 bug
一行短名字、短邮箱、带头像的数据渲染得很好。一行长名字、缺头像、字段为 null 的数据也渲染得很好。bug 在边界上,名字换行处、头像缺失处、字段是 null 而不是空串处、日期格式不在预期范围内处。单一的 mock 数据永远到不了边界,所以处理边界的格式化代码直到生产环境才第一次被运行。
解法不是更多行,而是更多样的行。五十行的数据集就够了,前提是这些行里包含一个长名字、一个非拉丁字符的名字、一个缺失的可选字段、一个期望数字却为 0 的字段、以及不止一种格式的日期。如果每一行都和第一行只差一个 id,这个数据集什么都测不到。
字段推断是捷径
手写 mock schema 很繁琐,所以人们跳过这步,把同一行粘贴十遍。字段推断反过来:你给工具一个样本 JSON 对象,它根据字段名和值推断每个字段是什么。叫 email 的字段生成看起来合理的邮箱。叫 avatar 的字段生成占位图 URL。叫 createdAt 的字段在你控制的范围内生成时间戳。叫 total 的字段生成量级正确的数字。
推断的意义不在于它百分百准确,而在于它免费产出多样、合理的值,让数据集不写生成器就能锻炼 UI。对名字常规的字段,推断大多是对的。对名字不常规的字段,你覆盖推断出的类型即可,但只是少数几个字段,而不是全部。
真正会破坏格式化的边界情况
名字字段在以下情况破坏布局:太长、在不寻常的位置含空格、含非拉丁文字。mock 数据集应至少各包含一个。长名字测你的布局是截断还是换行。非拉丁名字测你的字体栈和字符串处理是否正确。
日期字段在格式变化时出问题。如果你的格式化代码假设 ISO 8601,而 mock 数据全是 ISO 8601,代码工作正常。当生产环境发来秒级而不是毫秒级时间戳,代码会渲染出 1971 年的日期。在 mock 数据里包含两种格式,或至少一行格式异常的数据,bug 就会在开发期而不是用户工单里出现。
数字字段在边界处出问题:零、负数、非常大、以及小数位比你显示代码预期的多。一个 total 都在 100 到 500 之间的 mock 数据集这些都测不到。加一个零、一个负数、一个大数,舍入和对齐代码就得到了锻炼。
缺失字段,以及 null 与空串
真实 API 响应会省略字段、返回 null。你的渲染代码必须两者都处理,而它们是不同的。缺失字段在 JavaScript 里是 undefined。null 字段是 null。空串是 ""。每一种都可能破坏不同的代码路径,而能处理其中一种的代码常常处理不了另一种。
好的 mock 数据包含字段缺失的行、字段为 null 的行、以及字段为空串的行,这样 ?. 可选链、?? 空值合并、|| 兜底都得到测试。如果每行每个字段都在且非 null,防御性代码就从不运行,生产环境的第一个 null 就会抛错。
多少 mock 数据才够
五十行通常够了。一百行很充足。一千行只在测分页或虚拟滚动时才有用。常见的错误是生成一万行单一数据,只测了滚动性能,别的什么都没测。
从一个样本对象开始,生成五十行多样的数据,再手动加三四个推断没产出的边界情况:一个长名字、一个缺失的必填字段、一个格式不对的日期。手动加的这几行才是找 bug 的,生成的那些行只是让页面看起来有内容。
把 mock 数据和测试放在一起
放在共享文件里、被每个测试复用的 mock 数据会变得隐形。没人看它、没人更新它,它和真实 API 的形状慢慢漂移。API 变了,mock 数据没变,测试就在一个已经不存在的形状上通过。
把 mock 数据放在使用它的测试附近,在 API 变化时从当前样本重新生成,并把样本 JSON 当作真相源。本站的 Mock 工具从样本生成,所以当 API 形状变了,你粘贴新样本重新生成,而不是手工改一份过时的 fixture。
主要参考资料
用于核对本文技术细节的标准与官方文档。
从 JSON 样本生成贴近真实的 mock 数据
本站的 Mock 工具接收一个 JSON 样本,产出贴近真实的数组,并推断 email、avatar、id、total、timestamp 等字段,让你无需写 schema 就能得到多样的值。全部在浏览器里运行,样本不会离开你的机器。
打开 Mock 工具相关文章
继续阅读同一主题领域的实践指南。
Node 生产 Dockerfile 里到底该有什么,不该有什么
网上大多数 Node Dockerfile 都把 node_modules 直接拷进镜像、用 root 运行、最后产出一个 900 MB 的层。本文只讲那几个真正影响构建时间、镜像体积和运行时安全的决定:基础镜像、多阶段构建、依赖层缓存、NODE_ENV 陷阱,以及为什么你的 docker-compose 不该照搬生产。
在用户之前发现缺失的翻译键和插值参数不匹配
缺失的翻译键会把原始键路径直接渲染给用户,插值参数不匹配会渲染出空串或崩溃。这两者在评审中都容易漏,因为开发者的语言包永远有全部键。本文讲如何结构化比较 locale JSON 文件、找出缺失键,并在发布前抓住参数不匹配。
把 cURL 转成 fetch、Axios 或 Python,别丢了关键请求头
cURL 是 HTTP 调试的通用语,但把 cURL 命令直接粘进应用代码是范畴错误。本文讲转换到 fetch、Axios 和 Python requests 时什么能保留、什么会丢失,以及那些在转换中悄悄改变行为的请求头和 body 编码。