Skip to main content

testing-strategy

Vitest + Cypress + RTL — deterministic tests, ≥80% line / ≥70% branch coverage, ≥95% on security code, Three.js component testing

Quellinformationen

Repository
Hack23/game
Letzte Quellaktivität
17. April 2026 um 14:05
Erkannte Sprache von SKILL.md
Englisch
Sterne
13
Forks
5

Installationsoptionen

Standardmäßig ist der Prompt ausgewählt, der zuerst die Quelle prüft. Sie können zu einem direkten Befehl wechseln oder eine lokale Kopie herunterladen.

Quelldateien prüfen

Lesen Sie SKILL.md und alle von SkillsMP angezeigten Begleitdateien, bevor Sie sich für eine Installation entscheiden.

SKILL.md wird angezeigt

SKILL.md
Quellanweisungen · Schreibgeschützte Vorschau
name
testing-strategy
description
Vitest + Cypress + RTL — deterministic tests, ≥80% line / ≥70% branch coverage, ≥95% on security code, Three.js component testing
license
MIT
# Testing Strategy Skill ## Context Applies when writing unit tests, E2E tests, testing Three.js components, mocking dependencies, measuring coverage, diagnosing flakes, or preparing test data. Aligned with [Secure Development Policy §Unit Test Coverage & Quality](https://github.com/Hack23/ISMS-PUBLIC/blob/main/Secure_Development_Policy.md). ## Rules 1. **≥ 80 % line / ≥ 70 % branch coverage** across every module 2. **≥ 95 % coverage** on security-sensitive code (input validation, encoding, auth/authorization) 3. **Test pyramid** — many unit, fewer integration, fewest E2E 4. **Behavior, not implementation** — query by role/text; avoid internal-state checks 5. **AAA pattern** — Arrange → Act → Assert; one behavior per test 6. **Mock external dependencies** — APIs, timers, Three.js renderer — with proper types 7. **Cover error and edge cases** — not just the happy path 8. **React Testing Library** — prefer role/text queries; stable `data-testid` allowed on intent 9. **Test logic, not WebGL** — for Three.js, test state/logic; mock the renderer 10. **Isolate tests** — no shared mutable state; `vi.clearAllMocks()` in `beforeEach` 11. **Descriptive names** — "should \<behavior\> when \<condition\>" 12. **Deterministic** — mock `Date.now`, `Math.random`, timers; no real network 13. **Fast** — unit tests in ms, E2E in seconds; parallelize where safe 14. **No flaky tests** — fix the root cause, never retry blindly 15. **No production / PII data in tests** — anonymize or synthesize (per SDP §Test Data Protection) 16. **CI must pass** — no merging red ## Examples ### ✅ Component test with RTL ```tsx import { render, screen } from '@testing-library/react'; import { describe, it, expect, vi, beforeEach } from 'vitest'; import { HUD } from './HUD'; const mockGameState = { score: 42, isPlaying: true, timeLeft: 30, combo: 0, highScore: 100, targetSize: 0.5, level: 1, isNewHighScore: false, targets: [] as unknown[], totalClicks: 10, successfulHits: 5, } as const; describe('HUD', () => { beforeEach(() => { vi.clearAllMocks(); }); it('should display the current score', () => { render(<HUD gameState={mockGameState} />); expect(screen.getByText(/42/)).toBeInTheDocument(); }); }); ``` ### ✅ Pure-function (no Three.js) test ```typescript import { describe, it, expect } from 'vitest'; import { calculateLevel, getTargetCountForLevel } from './gameConfig'; describe('gameConfig', () => { it('should return level 1 for score 0', () => { expect(calculateLevel(0)).toBe(1); }); it('should return 1 target for levels 1-3', () => { expect(getTargetCountForLevel(1)).toBe(1); expect(getTargetCountForLevel(3)).toBe(1); }); }); ``` ### ✅ Mocking Three.js ```tsx import type { ReactNode } from 'react'; import { vi } from 'vitest'; vi.mock('@react-three/fiber', () => ({ Canvas: ({ children }: { children: ReactNode }) => <div>{children}</div>, useFrame: vi.fn(), useThree: () => ({ camera: {}, scene: {}, gl: {} }), })); vi.mock('@react-three/drei', () => ({ Sparkles: ({ children }: { children?: ReactNode }) => <>{children}</>, Trail: ({ children }: { children?: ReactNode }) => <>{children}</>, })); ``` ### ✅ Deterministic RNG ```typescript import { vi, afterEach } from 'vitest'; beforeEach(() => { const seq = [0.1, 0.2, 0.3]; let i = 0; vi.spyOn(Math, 'random').mockImplementation(() => seq[i++ % seq.length]); }); afterEach(() => { vi.restoreAllMocks(); }); ``` ### ✅ Security-path test (failure mode) ```typescript it('should reject non-finite scores', () => { expect(() => saveHighScore(Number.NaN)).toThrow(RangeError); expect(() => saveHighScore(Infinity)).toThrow(RangeError); expect(() => saveHighScore(-1)).toThrow(RangeError); }); ``` ### ❌ Anti-Patterns ```typescript // BAD: testing implementation expect(component.state.internalValue).toBe(5); // BAD: non-deterministic expect(result).toBe(Math.random()); // BAD: vague test name it('works', () => { /* … */ }); // BAD: shared state between tests let counter = 0; it('t1', () => { counter++; }); it('t2', () => { expect(counter).toBe(1); }); // order-dependent! // BAD: production data const user = { email: 'real.user@company.com' }; // PII in tests ``` ## Flaky-Test Triage 1. Reproduce locally with the same seed/time 2. Classify: timing / network / shared-state / order-dependence 3. Fix at the root (fake timers / explicit mocks / cleanup); never `retry` as a workaround 4. Add a regression test for the fix ## Validation Checklist - [ ] ≥ 80 % line / ≥ 70 % branch coverage on changed modules - [ ] ≥ 95 % coverage on security-sensitive code - [ ] Deterministic (no real clocks, RNG, network) - [ ] Three.js mocked in unit tests; logic tested in `src/utils/` - [ ] E2E covers at least one critical user flow for the feature - [ ] No production / PII data in fixtures - [ ] CI green locally (`npm run test:ci`, `npm run test:e2e:ci`)
Auf GitHub ansehen