← 中文资源

简体中文版本

测试分页的各种边界

覆盖空结果、恰好一页、最后一页、非法游标与排序键并列,确保客户端不会死循环或漏记录。

阅读英文原文

概述

多数分页测试只验证正常路径:一页数据、合法 limit、顺序正确。这样的测试对重复行、最后一页仍返回游标等缺陷毫无察觉。真正的 bug 在边界上:空集合、恰好一页、多出一行,以及已失效的游标。这些正是客户端依赖的算术。

步骤

  1. 把边界写成表格,断言页数而不只是第一页的状态码。
  2. 造出时间戳并列的数据,暴露排序不确定的问题。
  3. 遍历所有页并收集 id:
const seen = new Set();
do {
  const res = await request(`/api/events?limit=4${cursor ? `&cursor=${cursor}` : ''}`);
  for (const row of res.body.data) {
    assert.ok(!seen.has(row.id), `duplicate ${row.id}`);
    seen.add(row.id);
  }
  cursor = res.body.nextCursor;
} while (cursor);
assert.equal(seen.size, 11);
  1. 传入非法游标,断言返回 400 与稳定错误码,而不是空页或 500。
  2. 固定 limit 规则:0 收敛为 1,1000 收敛为 100,负数返回 400。

验证

11 行数据、每页 4 行时应得到 3 页,全部 id 各出现一次,最后一页的 nextCursor 为 null。三条时间戳相同的记录不应在页边界重复或丢失。非法游标返回 invalid_cursor,limit 越界按约定收敛或拒绝。

注意事项

  • 排序键必须唯一,使用 (created_at, id) 并把两者编码进游标。
  • 判断是否还有下一页应多取一行,而不是假设满页就代表还有数据。
  • keyset 分页能承受删除,offset 分页会整体偏移,需要同步的客户端应使用 keyset。
  • 游标是用户输入,必须验签或校验结构,不能直接拼进 SQL。
  • 部署后旧游标可能失效,应给游标加版本并在灰度期兼容旧格式。