Install any skill in seconds. Free to start, no credit card required.
Get Started Free →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.
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-05 | ✗→✓ | ▲ Improved | 8% | 0% |
| case-06 | ✗→✓ | ▲ Improved | 80% | 0% |
| case-01 | ✗→✓ | ▲ Improved | 54% | 0% |
| case-03 | ✗→✓ | ▲ Improved | 73% | 0% |
| case-04 | ✗→✓ | ▲ Improved | 175% | 0% |
This skill enables Codex 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/testing/testing.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 |
bash# 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> --review
ComponentName.spec.tsx (same directory as component)web/__tests__/ directorytypescriptimport { 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.md for 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:
typescript// ❌ 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:
typescript// ✅ 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>:
typescriptit('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/testing/testing.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.Other measured skills in the registry, with their headline benchmark lift.