Use when writing or reviewing JavaScript/TypeScript tests - Jest/Vitest assertions, React Testing Library queries, module mocking, async patterns, and snapshot discipline.
Resolve SKILL_DIR to the absolute directory containing this SKILL.md, as
shown by the current host, before using any bundled path below.
Before a shell command uses $SKILL_DIR, assign it in that command or replace
it with the resolved path. It is not a host-exported environment variable.
Jest, Vitest, and React Testing Library testing patterns. For shared test quality principles (philosophy, smells, mocking decisions), see testing-patterns.
| Need | Reference File | Sections to Read |
|------|---------------|-----------------|
| Jest/Vitest + RTL patterns | $SKILL_DIR/../testing-patterns/references/jest-vitest-patterns.md | Full file (~422L, manageable) |
| Behavior vs implementation | $SKILL_DIR/../testing-patterns/references/test-philosophy.md | ## The Fundamental Shift + ## Four Core Principles |
| Flaky/brittle tests | $SKILL_DIR/../testing-patterns/references/test-smells.md | ## The Six Major Test Smells (relevant subsection) |
| Mock usage decisions | $SKILL_DIR/../testing-patterns/references/mocking-strategies.md | ## The Mocking Decision Framework |
| AAA pattern/naming | $SKILL_DIR/../testing-patterns/references/test-structure.md | ## The AAA Pattern + ## Test Naming Conventions |
| Test data strategy | $SKILL_DIR/../testing-patterns/references/test-data.md | ## Factories + ## Builders |
How to read sections: Grep for heading to find line number, Read with offset+limit.
getByRole('button', { name: 'Submit' }) — accessible, resilientgetByLabelText('Email') — form elementsgetByPlaceholderText() — when no labelgetByText('Click me') — visible contentgetByDisplayValue() — filled inputsgetByTestId('submit-btn') — last resort| Use | Instead Of | Why |
|-----|-----------|-----|
| toMatchObject({key: val}) | toEqual({...all fields}) | Partial match, resilient to new fields |
| toHaveBeenCalledWith(x) | toHaveBeenCalled() | Verifies correct arguments |
| await expect(fn()).rejects.toThrow() | Missing await | Without await, assertion silently passes |
| userEvent.click() | fireEvent.click() | Simulates real user interaction |
| jest.useFakeTimers() | Real timers | Deterministic, no flakiness |
| toContainEqual(item) | toEqual([...all items]) | Checks membership, not exact array |
| Inline snapshots | toMatchSnapshot() on large output | Reviewed in PR diff, not hidden files |
| Pattern | Why Harmful | Fix |
|---------|------------|-----|
| toMatchSnapshot() on large components | Never meaningfully reviewed | Use inline snapshots or specific assertions |
| jest.mock() on owned modules | Tests mock wiring, not behavior | Test through public API |
| toEqual for partial checks | Breaks when fields added | Use toMatchObject |
| Missing await on async assertions | Silent pass | Always await expect(...).rejects |
| Blanket act() wrapping | Hides real act() warnings | Let RTL handle, wrap only when needed |
| Timer-dependent without fake timers | Flaky in CI | Use jest.useFakeTimers() |
| getByTestId as primary query | Tests implementation | Use role/label/text queries |
| fireEvent over userEvent | Not real interaction | Use @testing-library/user-event |
await or return the promisejest.useFakeTimers() + jest.advanceTimersByTime(ms)findBy* (waits) not getBy* (immediate) for async contentrender() handle; wrap only state updates outside RTLnpx skills add vladolaru/js-testing-patterns下载完整 Skill 目录,包含 SKILL.md 及所有相关文件
Search for places (restaurants, cafes, etc.) via Google Places API proxy on localhost.
Interact with GitHub using the `gh` CLI. Use `gh issue`, `gh pr`, `gh run`, and `gh api` for issues, PRs, CI runs, and advanced queries.
Create or update AgentSkills. Use when designing, structuring, or packaging skills with scripts, references, and assets.
Start voice calls via the OpenClaw voice-call plugin.
Notion API for creating and managing pages, databases, and blocks.
Gemini CLI for one-shot Q&A, summaries, and generation.
Category:developer