Files

3.9 KiB
Raw Permalink Blame History

id, title, type, domain, stack, tags, level, prerequisites, est_hours, related, week, order
id title type domain stack tags level prerequisites est_hours related week order
frontend.fe-testing-perf.testing 前端测试:Vitest 单元测试、Testing Library 组件测试、Playwright 端到端测试 lesson frontend
fe-testing-perf
Vitest
Testing Library
Playwright
假定时器
Mock
竞态
测试金字塔
intermediate
frontend.react.hooks-rendering
2.5
frontend.fe-testing-perf.web-vitals
frontend.fe-testing-perf.interview
ai.ai-coding.verify-evidence
7
1

前端测试:Vitest 单元测试、Testing Library 组件测试、Playwright 端到端测试

BOSS直聘 2026-10-23 的调研中,多个岗位要求“用 AI 写代码并保证质量”:测试是证明 AI 生成代码正确的最直接证据(见 AI 编程:验证与证据)。工具版本以官方文档为准:https://vitest.dev/ 、https://testing-library.com/ 、https://playwright.dev/ 。

解释说明

测试金字塔

层级 工具 测什么 数量
单元测试 Vitest 纯函数、状态机、工具函数、组合式函数 / Hooks 最多
组件测试 Vitest + Testing Library(jsdom) 组件在用户操作下的表现 适中
端到端测试 Playwright 真实浏览器中的关键业务流程 少而精

Testing Library 的原则

按用户的方式测试:通过角色、标签文字查找元素(getByRole、getByLabelText),而不是 CSS 类名或组件内部状态;断言用户能看到的结果。好处是重构实现时测试不用改,同时促使组件具备可访问性。

常用技巧

  • 假定时器:vi.useFakeTimers() + vi.advanceTimersByTimeAsync() 测试防抖、轮询、超时,不需要真的等待。
  • Mock:vi.fn() 模拟依赖(接口请求函数作为参数注入,测试时传入假的实现);端到端测试中用 page.route 拦截接口返回固定数据。
  • 测竞态:让旧请求比新请求慢,断言最终显示新结果。
  • 端到端测试稳定性:使用自动等待的断言(await expect(locator).toHaveCount(2)),不要写固定的 sleep。

案例

订单搜索框:防抖 300ms;输入变化时中止旧请求;失败显示错误。三个测试分别覆盖防抖、竞态和失败;把组件中的 controller.abort() 删除后,竞态测试会失败——证明测试真的在保护这个行为。

代码示例

完整示例:examples/search-box(vitest run:3 个测试通过;tsc 通过;删除中止逻辑后竞态测试失败,已验证)。

it("竞态:慢的旧请求晚返回,不会覆盖新结果", async () => {
  const search: SearchFn = (q, signal) =>
    new Promise((resolve) => {
      const ms = q === "old" ? 1000 : 100;
      const t = setTimeout(() => resolve([`结果-${q}`]), ms);
      signal.addEventListener("abort", () => clearTimeout(t));
    });
  render(<SearchBox search={search} />);
  typeInto("old");
  await act(() => vi.advanceTimersByTimeAsync(300));
  typeInto("new");
  await act(() => vi.advanceTimersByTimeAsync(2000));
  expect(screen.getByRole("list", { name: "搜索结果" }).textContent).toBe("结果-new");
});

Playwright 端到端测试(示意,未在浏览器中实际运行):e2e/search.spec.ts。

易错点

  • 测试实现细节(组件内部 state、私有方法),重构就挂。
  • 用真实定时器等待,测试又慢又不稳定。
  • 组件内部直接 fetch,测试只能 mock 全局对象:把依赖作为参数或通过上下文注入更好测。
  • 端到端测试依赖测试环境的真实数据,数据一变就失败。
  • 只追求覆盖率数字:没有断言的测试也能提高覆盖率。

面试常问

  • 你们项目怎么做前端测试?测试金字塔每层测什么?
  • 怎么测试防抖、定时器、异步请求?
  • 端到端测试不稳定怎么办?