testing
2
总安装量
2
周安装量
#65561
全站排名
安装命令
npx skills add https://github.com/xmenq/template-agentic-coding --skill Testing
Agent 安装分布
cline
2
gemini-cli
2
github-copilot
2
codex
2
kimi-cli
2
cursor
2
Skill 文档
Testing Skill
When to use this skill
Use when writing tests of any kind: unit, integration, end-to-end, or when designing a testing strategy for a new feature.
Testing Philosophy
Core beliefs
- Test behavior, not implementation. Tests should describe what the code does, not how it does it internally. If a refactor breaks your tests, the tests were wrong.
- Tests are documentation. A well-written test suite tells you exactly what the system does and what edge cases exist.
- Fast feedback > complete coverage. A fast test suite that runs on every change beats a slow, comprehensive suite that nobody runs.
- One assertion per test concept. Each test should verify one behavior. If it fails, you know exactly what broke.
Test Pyramid
â± E2E â² Few â slow, expensive, high confidence
â±ââââââââââ²
â±Integrationâ² Some â moderate speed, test component interactions
â±ââââââââââââââ²
â± Unit Tests â² Many â fast, cheap, test logic in isolation
â±ââââââââââââââââââ²
| Level | What it tests | Speed | Count |
|---|---|---|---|
| Unit | Single function/class in isolation | < 10ms each | Many (80%+) |
| Integration | Multiple components working together | < 1s each | Some (15%) |
| E2E | Full user workflows through real UI | < 30s each | Few (5%) |
Unit Tests
Structure: Arrange-Act-Assert (AAA)
// ARRANGE â set up the test data and dependencies
const user = createTestUser({ name: "Alice" })
const service = new UserService(mockRepo)
// ACT â perform the action being tested
const result = service.updateName(user.id, "Bob")
// ASSERT â verify the outcome
expect(result.name).toBe("Bob")
Naming convention
Test names should read like sentences:
â
"returns empty list when no orders exist"
â
"throws ValidationError when email is invalid"
â
"sends notification email after successful signup"
â "test1"
â "testUpdateUser"
â "it works"
What to unit test
- All business logic in
service/layer - Data transformation functions
- Validation logic
- Error handling paths
- Edge cases: empty input, null, boundary values, overflow
What NOT to unit test
- Framework boilerplate (routing config, middleware registration)
- Simple getters/setters with no logic
- Third-party library internals
- Database queries (save for integration tests)
Integration Tests
What to test
- Database queries (repo layer with real/test database)
- API endpoints (HTTP request â response)
- Component interactions (service A calls service B)
- External service integrations (with containerized dependencies)
Rules
- Use a real test database (not mocks) â spin up with Docker or in-memory
- Reset state between tests â each test starts with a clean slate
- Seed realistic data â don’t test with just one row
- Test the unhappy paths â what happens when the DB is down, the API returns 500?
End-to-End Tests
What to test
- Critical user journeys â signup, login, purchase, core workflows
- Cross-page flows â navigation, multi-step forms, redirects
- Only test the happy path + most important failure per journey
Rules
- Keep E2E tests minimal â they’re slow and fragile
- Use stable selectors â
data-testidattributes, not CSS classes - Wait for elements â never use fixed sleep/delays
- Isolate test data â each test creates its own data, cleans up after
- Record failures â capture screenshots/video on test failure
E2E test structure
describe("User signup flow")
it("creates account with valid details")
â navigate to signup page
â fill in form fields
â submit
â verify redirect to dashboard
â verify welcome message displayed
it("shows error for duplicate email")
â navigate to signup page
â fill in form with existing email
â submit
â verify error message displayed
â verify user stays on signup page
Test Data
Rules
- Never use production data in tests
- Use factories/builders to create test data â not raw constructors
- Make test data realistic â use realistic names, emails, amounts
- Randomize where appropriate â catch assumptions with random data
- Clean up â delete test data after each test run
Test data pattern
// Factory pattern â create test data with sensible defaults
function createTestUser(overrides = {}) {
return {
id: generateId(),
name: "Test User",
email: "test@example.com",
role: "user",
...overrides // allow overriding any field
}
}
// Usage
const admin = createTestUser({ role: "admin" })
const unverified = createTestUser({ isVerified: false })
Mocking
When to mock
- External services (APIs, payment providers, email)
- Time-dependent logic (use a clock mock)
- Randomness (seed the random generator)
- Expensive operations (file I/O, network calls)
When NOT to mock
- Your own code (test the real implementation)
- The database (use a test database instead)
- Simple utility functions
Mocking rules
- Mock at the boundary â mock the external interface, not internal details
- Verify mock interactions sparingly â prefer asserting on outputs over inputs
- Keep mocks simple â if your mock is complex, the design might need rethinking
Common Anti-Patterns
| Anti-pattern | Problem | Fix |
|---|---|---|
| Testing implementation details | Tests break on refactor | Test behavior and outputs instead |
| Shared mutable test state | Tests affect each other | Reset state before each test |
| Sleep/delay in tests | Slow, flaky | Use proper async waiting/polling |
| Ignored/skipped tests | Dead weight that rots | Fix or delete them immediately |
| Asserting on error messages | Fragile to wording changes | Assert on error codes/types |
| One giant test file | Hard to navigate | One test file per source file |
| Testing private methods | Couples to implementation | Test through the public API |
Coverage
- Don’t chase 100% coverage â it’s expensive and gives false confidence
- Target: 80%+ for service/business logic, 60%+ overall
- Coverage is a floor, not a ceiling â meaningful tests matter more than the number
- Uncovered code should be intentional â add a comment if you deliberately skip testing something
PR Checklist for Tests
- New logic has corresponding unit tests
- Tests follow AAA structure (Arrange-Act-Assert)
- Test names read like sentences
- Edge cases covered (empty, null, boundary, error)
- No
sleep/fixed delays â uses proper async waiting - No shared mutable state between tests
- Test data uses factories, not raw constructors
- Mocks are at the boundary only
- All tests pass locally (
./scripts/dev/test)