ワンクリックで
frontend-testing
// Generate Vitest + React Testing Library tests for frontend components, hooks, and utilities. Triggers on testing, spec files, coverage, Vitest, RTL, unit tests, integration tests, or write/review test requests.
// Generate Vitest + React Testing Library tests for frontend components, hooks, and utilities. Triggers on testing, spec files, coverage, Vitest, RTL, unit tests, integration tests, or write/review test requests.
Guides creation of comprehensive Product Requirement Documents (PRDs) for software projects through structured questioning and validation, then generates implementation task lists in JSON format. Use when users want to document a software idea, create specifications for development, plan a new application feature/bug, or break down requirements into actionable tasks. Transforms ideas into implementation-ready documents with verifiable pass criteria.
Refactor high-complexity React components in frontend. Use when the user asks for code splitting, hook extraction, or complexity reduction, or when you come across a component that is too complex to understand and refactor it.
Playwright E2E testing patterns. Trigger: When writing Playwright E2E tests (Page Object Model, selectors, MCP exploration workflow).
Trigger when the user requests a review of frontend files (e.g., `.tsx`, `.ts`, `.js`). Support both pending-change reviews and focused file reviews while applying the checklist rules.
Guide for creating effective skills. This skill should be used when users want to create a new skill (or update an existing skill) that extends Claude's capabilities with specialized knowledge, workflows, or tool integrations.
Comprehensive vitest testing patterns covering test structure, AAA pattern, parameterized tests, assertions, mocking, test doubles, error handling, async testing, and performance optimization. Use when writing, reviewing, or refactoring vitest tests, or when user mentions vitest, testing, TDD, test coverage, mocking, assertions, or test files (*.test.ts, *.spec.ts).
| name | frontend-testing |
| description | Generate Vitest + React Testing Library tests for frontend components, hooks, and utilities. Triggers on testing, spec files, coverage, Vitest, RTL, unit tests, integration tests, or write/review test requests. |
This skill enables Claude to generate high-quality, comprehensive frontend tests following established conventions and best practices.
Apply this skill when the user:
Do NOT apply when:
| Tool | Version | Purpose |
|---|---|---|
| Vitest | 4+ | Test runner |
| React Testing Library | 16+ | Component testing |
| jsdom | - | Test environment |
| TypeScript | 5+ | Type safety |
Note: keep this list up to date with the project's dependencies.
Always prefer running specific tests over the entire suite for faster feedback:
# Run ALL tests (avoid during development)
npx vitest run
# ✅ PREFERRED: Run specific file
npx vitest run src/components/Button.spec.tsx
# ✅ PREFERRED: Run tests matching a pattern
npx vitest run --grep "Button"
npx vitest run -t "should render"
# ✅ PREFERRED: Run specific describe block
npx vitest run --grep "Button > Rendering"
# ✅ Run tests in a directory
npx vitest run src/components/
# ✅ Run single test by name
npx vitest run -t "should disable button when loading"
Use watch mode for efficient iterative development:
# ✅ Watch mode - reruns on file changes
npx vitest
# ✅ Watch specific file
npx vitest src/components/Button.spec.tsx
# ✅ Watch tests matching pattern
npx vitest --grep "Button"
ComponentName.spec.tsx (same directory as component)import { render, screen, fireEvent, waitFor } from '@testing-library/react'
import Component from './index'
// ✅ Import real project components (DO NOT mock these)
// import Loading from '@/app/components/base/loading'
// import { ChildComponent } from './child-component'
// ✅ Mock external dependencies only
vi.mock('@/service/api')
vi.mock('next/navigation', () => ({
useRouter: () => ({ push: vi.fn() }),
usePathname: () => '/test',
}))
// Shared state for mocks (if needed)
let mockSharedState = false
describe('ComponentName', () => {
beforeEach(() => {
vi.clearAllMocks() // ✅ Reset mocks BEFORE each test
mockSharedState = false // ✅ Reset shared state
})
// Rendering tests (REQUIRED)
describe('Rendering', () => {
it('should render without crashing', () => {
// Arrange
const props = { title: 'Test' }
// Act
render(<Component {...props} />)
// Assert
expect(screen.getByText('Test')).toBeInTheDocument()
})
})
// Props tests (REQUIRED)
describe('Props', () => {
it('should apply custom className', () => {
render(<Component className="custom" />)
expect(screen.getByRole('button')).toHaveClass('custom')
})
})
// User Interactions
describe('User Interactions', () => {
it('should handle click events', () => {
const handleClick = vi.fn()
render(<Component onClick={handleClick} />)
fireEvent.click(screen.getByRole('button'))
expect(handleClick).toHaveBeenCalledTimes(1)
})
})
// Edge Cases (REQUIRED)
describe('Edge Cases', () => {
it('should handle null data', () => {
render(<Component data={null} />)
expect(screen.getByText(/no data/i)).toBeInTheDocument()
})
it('should handle empty array', () => {
render(<Component items={[]} />)
expect(screen.getByText(/empty/i)).toBeInTheDocument()
})
})
})
NEVER generate all test files at once. For complex components or multi-file directories:
For each file:
┌────────────────────────────────────────────────┐
│ 1. Write test │
│ 2. Run: npm run test-unit <file>.spec.tsx │
│ 3. PASS? → Mark complete, next file │
│ FAIL? → Fix first, then continue │
└────────────────────────────────────────────────┘
Process in this order for multi-file testing:
When assigned to test a directory/path, test ALL content within that path:
index file)Prefer integration testing when writing tests for a directory:
@/service/*), next/navigation, complex context providers@/app/components/base/*)Every test should clearly separate:
// ❌ Avoid: hardcoded text assertions
expect(screen.getByText('Loading...')).toBeInTheDocument()
// ✅ Better: role-based queries
expect(screen.getByRole('status')).toBeInTheDocument()
// ✅ Better: pattern matching
expect(screen.getByText(/loading/i)).toBeInTheDocument()
Each test verifies ONE user-observable behavior:
// ✅ Good: One behavior
it('should disable button when loading', () => {
render(<Button loading />)
expect(screen.getByRole('button')).toBeDisabled()
})
// ❌ Bad: Multiple behaviors
it('should handle loading state', () => {
render(<Button loading />)
expect(screen.getByRole('button')).toBeDisabled()
expect(screen.getByText('Loading...')).toBeInTheDocument()
expect(screen.getByRole('button')).toHaveClass('loading')
})
Use should <behavior> when <condition>:
it('should show error message when validation fails')
it('should call onSubmit when form is valid')
it('should disable input when isReadOnly is true')
| Feature | Test Focus |
|---|---|
useState | Initial state, transitions, cleanup |
useEffect | Execution, dependencies, cleanup |
| Event handlers | All onClick, onChange, onSubmit, keyboard |
| API calls | Loading, success, error states |
| Routing | Navigation, params, query strings |
useCallback/useMemo | Referential equality |
| Context | Provider values, consumer behavior |
| Forms | Validation, submission, error display |
For each test file generated, aim for:
Note: For multi-file directories, process one file at a time with full coverage each. See
references/workflow.md.
For more detailed information, refer to:
references/workflow.md - Incremental testing workflow (MUST READ for multi-file testing)references/mocking.md - Mock patterns and best practicesreferences/async-testing.md - Async operations and API callsreferences/common-patterns.md - Frequently used testing patternsreferences/checklist.md - Test generation checklist and validation stepsvitest.config.ts - Vitest configurationvitest.setup.ts - Test environment setupvitest.setup.ts (for example react-i18next, next/image); mock other modules like ky or mime locally in test files.