标准答案

  1. Testing Library 鼓励从用户视角测试组件,不直接依赖组件实例、内部 state 或私有方法。
  2. 查询元素时优先使用 getByRole、getByLabelText、getByText 等接近可访问语义的方式。
  3. 交互应使用 userEvent 模拟真实用户输入、点击、键盘操作,而不是只触发底层事件。
  4. 断言重点应该是页面结果、可见文本、按钮状态、表单错误、回调是否按用户行为触发。
  5. 它适合组件行为测试,不适合替代单元测试、E2E 测试或性能测试。

题目解析

这道题的重点是测试理念,而不是 API 名称。Testing Library 反对围绕实现细节写脆弱测试。

按 role 和 label 查询也会倒逼组件具备更好的可访问性。如果按钮没有可访问名称,测试不好写,用户也可能不好用。

组件重构时,只要用户行为和页面输出不变,Testing Library 风格的测试通常更稳定。

代码示例

下面的测试验证用户点击提交后看到了错误提示,而不是检查组件内部 state。

TSX
it('shows validation message when name is empty', async () => {
  render(<UserForm />)

  await userEvent.click(screen.getByRole('button', { name: '提交' }))

  expect(screen.getByText('请输入姓名')).toBeInTheDocument()
})

常见误区

  • 用 className、DOM 层级或测试 id 作为首选查询方式,测试和实现结构强耦合。
  • 只测组件内部函数是否被调用,没有验证用户能看到的结果。
  • 把 Testing Library 当作 E2E 工具,试图覆盖完整跨页面业务链路。

作者信息