Generate Vitest + React Testing Library tests for Dify frontend components, hooks, and utilities. Triggers on testing, spec files, coverage, Vitest, RTL, unit tests, integration tests, or write/review test requests.
Overall
score
91%
Does it follow best practices?
Validation for skill structure
This skill enables Claude to generate high-quality, comprehensive frontend tests for the Dify project following established conventions and best practices.
⚠️ Authoritative Source: This skill is derived from
web/docs/test.md. Use Vitest mock/timer APIs (vi.*).
Apply this skill when the user:
pnpm analyze-component output as contextDo NOT apply when:
| Tool | Version | Purpose |
|---|---|---|
| Vitest | 4.0.16 | Test runner |
| React Testing Library | 16.0 | Component testing |
| jsdom | - | Test environment |
| nock | 14.0 | HTTP mocking |
| TypeScript | 5.x | Type safety |
# Run all tests
pnpm test
# Watch mode
pnpm test:watch
# Run specific file
pnpm test path/to/file.spec.tsx
# Generate coverage report
pnpm test:coverage
# Analyze component complexity
pnpm analyze-component <path>
# Review existing test
pnpm analyze-component <path> --reviewComponentName.spec.tsx (same directory as component)web/__tests__/ directoryimport { 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',
}))
// ✅ Zustand stores: Use real stores (auto-mocked globally)
// Set test state with: useAppStore.setState({ ... })
// 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: pnpm test <file>.spec.tsx │
│ 3. PASS? → Mark complete, next file │
│ FAIL? → Fix first, then continue │
└────────────────────────────────────────┘Process in this order for multi-file testing:
📖 See
references/workflow.mdfor complete workflow details and todo list format.
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/*)See Test Structure Template for correct import/mock patterns.
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, Zustand store testing, and best practicesreferences/async-testing.md - Async operations and API callsreferences/domain-components.md - Workflow, Dataset, Configuration testingreferences/common-patterns.md - Frequently used testing patternsreferences/checklist.md - Test generation checklist and validation stepsweb/docs/test.md - The canonical testing specification. This skill is derived from this document.web/utils/classnames.spec.ts - Utility function testsweb/app/components/base/button/index.spec.tsx - Component testsweb/__mocks__/provider-context.ts - Mock factory exampleweb/vitest.config.ts - Vitest configurationweb/vitest.setup.ts - Test environment setupweb/scripts/analyze-component.js - Component analysis toolweb/vitest.setup.ts (for example react-i18next, next/image); mock other modules like ky or mime locally in test files.If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.