chore: add anthropic skills for frontend testing (#29608)

Signed-off-by: yyh <yuanyouhuilyz@gmail.com>
Co-authored-by: autofix-ci[bot] <114827586+autofix-ci[bot]@users.noreply.github.com>
This commit is contained in:
yyh
2025-12-15 10:05:48 +08:00
committed by GitHub
parent 3db27c3158
commit 61199663e7
12 changed files with 3166 additions and 5 deletions

View File

@@ -42,7 +42,7 @@ pnpm test -- path/to/file.spec.tsx
## Test Authoring Principles
- **Single behavior per test**: Each test verifies one user-observable behavior.
- **Black-box first**: Assert external behavior and observable outputs, avoid internal implementation details.
- **Black-box first**: Assert external behavior and observable outputs, avoid internal implementation details. Prefer role-based queries (`getByRole`) and pattern matching (`/text/i`) over hardcoded string assertions.
- **Semantic naming**: Use `should <behavior> when <condition>` and group related cases with `describe(<subject or scenario>)`.
- **AAA / GivenWhenThen**: Separate Arrange, Act, and Assert clearly with code blocks or comments.
- **Minimal but sufficient assertions**: Keep only the expectations that express the essence of the behavior.
@@ -93,6 +93,7 @@ Use `pnpm analyze-component <path>` to analyze component complexity and adopt di
- Testing time-based behavior (delays, animations)
- If you mock all time-dependent functions, fake timers are unnecessary
1. **Prefer importing over mocking project components**: When tests need other components from the project, import them directly instead of mocking them. Only mock external dependencies, APIs, or complex context providers that are difficult to set up.
1. **DO NOT mock base components**: Never mock components from `@/app/components/base/` (e.g., `Loading`, `Button`, `Tooltip`, `Modal`). Base components will have their own dedicated tests. Use real components to test actual integration behavior.
**Why this matters**: Mocks that don't match actual behavior can lead to:
@@ -101,6 +102,43 @@ Use `pnpm analyze-component <path>` to analyze component complexity and adopt di
- **Maintenance burden**: Tests become misleading documentation
- **State leakage**: Tests interfere with each other when shared state isn't reset
## Path-Level Testing Strategy
When assigned to test a **directory/path** (not just a single file), follow these guidelines:
### Coverage Scope
- Test **ALL files** in the assigned directory, not just the entry `index` file
- Include all components, hooks, utilities within the path
- Goal: 100% coverage of the entire directory contents
### Test Organization
Choose based on directory complexity:
1. **Single spec file (Integration approach)** - Preferred for related components
- Minimize mocking - use real project components
- Test actual integration between components
- Only mock: API calls, complex context providers, third-party libs
1. **Multiple spec files (Unit approach)** - For complex directories
- One spec file per component/hook/utility
- More isolated testing
- Useful when components are independent
### Integration Testing First
When using a single spec file:
-**Import real project components** directly (including base components and siblings)
-**Only mock**: API services (`@/service/*`), `next/navigation`, complex context providers
-**DO NOT mock** base components (`@/app/components/base/*`)
-**DO NOT mock** sibling/child components in the same directory
> See [Example Structure](#example-structure) for correct import/mock patterns.
## Testing Components with Dedicated Dependencies
When a component has dedicated dependencies (custom hooks, managers, utilities) that are **only used by that component**, use the following strategy to balance integration testing and unit testing.
@@ -231,8 +269,16 @@ const mockGithubStar = (status: number, body: Record<string, unknown>, delayMs =
import { render, screen, fireEvent, waitFor } from '@testing-library/react'
import Component from './index'
// Mock dependencies
// ✅ Import real project components (DO NOT mock these)
// import Loading from '@/app/components/base/loading'
// import { ChildComponent } from './child-component'
// ✅ Mock external dependencies only
jest.mock('@/service/api')
jest.mock('next/navigation', () => ({
useRouter: () => ({ push: jest.fn() }),
usePathname: () => '/test',
}))
// Shared state for mocks (if needed)
let mockSharedState = false
@@ -379,9 +425,9 @@ describe('Component', () => {
## Coverage Goals
### ⚠️ MANDATORY: Complete Coverage in Single Generation
### ⚠️ MANDATORY: Complete Coverage Per File
Aim for 100% coverage:
When generating tests for a **single file**, aim for 100% coverage in that generation:
- ✅ 100% function coverage (every exported function/method tested)
- ✅ 100% statement coverage (every line executed)