← ClaudeAtlas

fec-component-testinglisted

Use when authoring or reviewing frontend unit, component, or light integration tests close to UI code, including React Testing Library, Vue Test Utils, hooks/composables, props/emits, callbacks, accessible queries, user-event interactions, mocks, loading/error/empty states, and regression coverage. For layer planning, real-browser journeys, or existing validation failures, choose the matching testing or validation workflow first; Chinese triggers include 组件测试, 组件单测, 单元测试, 轻量集成测试.
bovinphang/frontend-craft · ★ 14 · Testing & QA · score 80
Install: claude install-skill bovinphang/frontend-craft
# 组件测试 ## Purpose 用贴近代码和用户行为的测试验证纯逻辑、组件契约与轻量模块协作,减少重构和 UI 交互回归。 ## Procedure ### 1. 先确定测试层级 - 单元测试:纯函数、hooks/composables、utils、状态逻辑、schema。 - 组件测试:props/emits、回调、用户交互、loading/error/empty、mock 边界。 - 轻量集成测试:表单 + API mock + Router/Store/Provider 上下文。 跨页面真实浏览器流程分流到 E2E workflow;测试层选择不清楚时先做测试分层规划。 ### 2. 优先按用户可感知行为测试 每个测试保持 Arrange / Act / Assert 清晰分段:准备数据和渲染、执行用户动作、断言用户可见结果或公开契约。 ```tsx import { render, screen } from "@testing-library/react"; import userEvent from "@testing-library/user-event"; import { SearchBox } from "./SearchBox"; test("submits the entered keyword", async () => { const user = userEvent.setup(); const onSearch = vi.fn(); render(<SearchBox onSearch={onSearch} />); await user.type(screen.getByRole("searchbox", { name: /keyword/i }), "orders"); await user.click(screen.getByRole("button", { name: /search/i })); expect(onSearch).toHaveBeenCalledWith("orders"); }); ``` ### 3. Vue 组件使用可访问查询或明确文本断言 ```ts import { mount } from "@vue/test-utils"; import UserMenu from "./UserMenu.vue"; test("emits logout when the logout item is clicked", async () => { const wrapper = mount(UserMenu, { props: { userName: "Ada" }, }); await wrapper.get('[data-testid="logout-button"]').trigger("click"); expect(wrapper.emitted("logout")).toHaveLength(1); }); ``` 优先使用角色、标签和可见文本;仅在没有稳定语义时使用 `data-testid`。 ### 4. 控制 mock 边界 ```ts vi.mock("../api/users", () => ({ fetchUsers: vi.fn(async () => [{ id: "1", name: "Ada" }]), })); ``` - mock 网络、时间、路由和浏览