跳到正文
教程31 篇

测试与交付第 1 / 3 篇

测试全绿却不好用?写能抓住错误的验收

用“取消收藏后刷新”拆开纯逻辑、接口和浏览器检查。

进阶约 25 分钟练习资料核实

学习目标

三层少而有效的测试选择,以及一条能识别错误实现的验收用例。

适用场景

虚构需求:用户取消收藏后,刷新页面仍为未收藏;失败时应保留原状态。测试如果只检查按钮文案变化,就会漏掉“根本没写入服务端”。示例路由和按钮名须映射为你的实际产品。

准备条件

  • 从已确认需求写出预期,不复制当前实现作为答案。
  • 隔离测试账户和测试数据,能复原一条收藏记录。

操作步骤

  1. 先写用户能观察到的反例

    把“支持取消收藏”展开为操作和持久化结果。正常、失败、刷新各写一个预期。最有价值的问题是:一个错误实现会在哪一步被抓住?只断言处理函数被调用,通常还不足以证明数据已改变。

    验收前先写下错误实现
    A:只把按钮文字改成“收藏”,没有请求服务端。
    B:接口返回失败,但页面仍显示成功。
    C:列表已更新,详情缓存仍显示旧状态。
    目标用例应能分别识别这些错误;实际是否能识别需要运行确认。
  2. 把不同责任放到合适层级

    排序或参数校验用纯逻辑检查;身份与持久化用隔离数据库的接口检查;用户操作与刷新串联用少量浏览器检查。不要每种参数组合都启动浏览器,也不要只测模拟数据库来声称真实写入正确。

  3. 让浏览器按用户能识别的元素操作

    优先使用语义角色和可见名称;点击前注册写入响应等待,确认服务端结果后再刷新,避免乐观更新提前改按钮造成竞态。每个用例独立准备与清理数据。片段需由夹具提供 ownSavedItemUrl、实际 cancelEndpoint 与 cancelMethod;这里约定成功响应表示写入完成,异步任务或业务错误码需按真实契约另验完成信号。

    Playwright 核心片段,需接入项目测试夹具
    // 前置:夹具创建当前测试用户的一条已收藏记录。
    await page.goto(ownSavedItemUrl);
    const confirmation = page.waitForResponse(response =>
      response.url() === cancelEndpoint && response.request().method() === cancelMethod);
    await page.getByRole("button", { name: "取消收藏", exact: true }).click();
    const response = await confirmation;
    expect(response.ok()).toBeTruthy(); // 本例契约:成功响应代表写入完成
    await expect(page.getByRole("button", { name: "收藏", exact: true })).toBeVisible();
    await page.reload();
    await expect(page.getByRole("button", { name: "收藏", exact: true })).toBeVisible();
    // 另立失败用例:模拟接口失败,断言原状态和错误说明均保留。
  4. 验证测试会失败,再看它通过

    在隔离分支临时绕过持久化或模拟失败响应,观察该用例是否按预期报错,然后恢复代码。不要提交故意破坏的版本。若无论代码对错都通过,修测试;若只在偶然时间窗口失败,检查数据隔离和等待条件,不盲目加 sleep。

常见误区

用同一个实现函数计算测试预期。
预期应来自独立业务例子,否则同一个错误会被复制两遍。
把真实外部服务的偶发故障混进常规回归。
常规回归用受控边界,外部集成另做有条件验证并如实记录。

验收清单

  • 取消后的持久化结果经过刷新验证。
  • 失败用例能识别假成功。
  • 测试数据不依赖执行顺序。
  • 用例是否能抓住目标错误有验证记录。

资料与版本

本文为原创方法整理,示例与提示词需按项目调整;不代表真实用户研究或账号执行结果。