skills/behavior-testing/SKILL.md
# Behavior Testing Skill ## Trigger - Nach Feature-Implementation - Wenn Tests nur DOM-Rendering pruefen ("smoke tests") - Wenn Code-Review Luecken in der Test-Abdeckung findet - `/behavior-tests` Slash-Command ## Problem Standard-Tests (via AI-Generation oder Copilot) pruefen oft nur "wird gerendert?", nicht "funktioniert es?". Das fuehrt zu: - Buttons ohne Funktionalitaet bestehen alle Tests - API-Aufrufe mit falschen Argumenten werden nie erkannt - State-Verlust bei Navigation/Re-Mount blei
npx skillsauth add svenja-dev/claude-code-skills skills/behavior-testingInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
/behavior-tests Slash-CommandStandard-Tests (via AI-Generation oder Copilot) pruefen oft nur "wird gerendert?", nicht "funktioniert es?". Das fuehrt zu:
Was: Verifiziere, dass API-Funktionen mit den richtigen Argumenten aufgerufen werden. Warum: Falsche Argumente (fehlende Language-Parameter, falsche Endpoints) sind unsichtbar in Rendering-Tests.
// SCHLECHT: Prueft nur DOM
it('sends message', async () => {
await sendMessage('hello');
expect(screen.getByText('hello')).toBeInTheDocument(); // DOM only!
});
// GUT: Prueft API-Contract
it('sends message with correct language', async () => {
await sendMessage('hello');
expect(mockApi).toHaveBeenCalledWith(
'hello',
expect.any(Array), // history
'en', // language code
);
});
Checkliste:
vi.fn()toHaveBeenCalledWithtoHaveBeenCalledTimesWas: Verifiziere, dass State nach Re-Mount, Page-Refresh oder Auth-Wechsel korrekt bleibt. Warum: sessionStorage/localStorage-Bugs, Zustand-Resets bei Login/Logout.
// Prueft sessionStorage-Persistenz
it('persists counter to sessionStorage', async () => {
render(<Chat />);
await sendMessage('test');
expect(sessionStorage.getItem('key')).toBe('1');
});
// Prueft Auth-Transition
it('resets counter on login', () => {
sessionStorage.setItem('key', '5');
useAuthStore.setState({ isAuthenticated: true });
// Effect should reset
expect(sessionStorage.getItem('key')).toBe('0');
});
Checkliste:
setState manipulieren fuer Edge-CasesWas: Verifiziere, dass Fehler dem User angezeigt werden und die App nicht crasht. Warum: Fehlende Error-UI ist die haeufigste UX-Luecke.
// API-Fehler -> Error-UI
it('shows error on checkout failure', async () => {
mockPost.mockRejectedValueOnce(new Error('Server error'));
fireEvent.click(checkoutButton);
await waitFor(() => {
expect(screen.getByText(/error|fehler/i)).toBeInTheDocument();
});
});
// 204 No Content -> kein Crash
it('handles 204 No Content', async () => {
mockFetch({ ok: true, status: 204, text: () => Promise.resolve('') });
const result = await apiClient.get('/api/logout');
expect(result).toEqual({});
});
Checkliste:
Was: Verifiziere Input-Validation, Auth-Gates und Redirect-Sicherheit. Warum: XSS-Praevention, Open-Redirect-Verhinderung, Rate-Limit-Enforcement.
// Input-Laenge
it('rejects input over 2000 chars', async () => {
await sendMessage('a'.repeat(2001));
expect(mockApi).not.toHaveBeenCalled();
expect(screen.getByText(/maximum/i)).toBeInTheDocument();
});
// URL-Validation
it('blocks non-stripe.com redirect URLs', async () => {
mockPost.mockResolvedValueOnce({ url: 'https://evil.com/steal' });
fireEvent.click(checkoutButton);
await waitFor(() => {
expect(screen.getByText(/error/i)).toBeInTheDocument();
});
});
// CSRF-Token
it('attaches CSRF token to POST but not GET', async () => {
document.cookie = 'csrf_token=abc123';
await apiClient.post('/api/data', {});
expect(fetchMock).toHaveBeenCalledWith(
expect.any(String),
expect.objectContaining({
headers: expect.objectContaining({ 'X-CSRF-Token': 'abc123' }),
}),
);
});
Checkliste:
toBeInTheDocument() nutzen.vi.mock() fuer Service-Module, vi.fn() fuer einzelne Funktionen.useAuthStore.setState({...}) statt ueber UI navigieren.toHaveBeenCalledWith() ist wichtiger als toBeInTheDocument().try/catch im Produktionscode braucht einen Test.# Bestehende Rendering-Tests behalten:
ComponentName.test.tsx
# Neue Behavior-Tests daneben:
ComponentName.behavior.test.tsx
# Oder in describe-Bloecken trennen:
describe('rendering', () => { ... }); // bestehend
describe('behavior', () => { ... }); // neu
describe('error handling', () => { ... }); // neu
| Anti-Pattern | Problem | Loesung |
|-------------|---------|---------|
| Nur toBeInTheDocument() | Prueft nicht ob Button funktioniert | toHaveBeenCalledWith() |
| Kein API-Mock | Test ruft echte API auf | vi.mock() + vi.fn() |
| Happy-Path only | Fehler-UI wird nie getestet | mockRejectedValueOnce() |
| State-Annahmen | Store wird nicht zurueckgesetzt | beforeEach + setState |
| Kein Auth-Kontext | Tests laufen nur als eingeloggt | Teste beide Zustaende |
Siehe: Website/Relaunch 2026 01/services/__tests__/apiClient.test.ts (Error-Boundary + Security-Boundary Muster)
Siehe: Website/Relaunch 2026 01/components/__tests__/MultilingualChat.behavior.test.tsx (API-Contract + State-Persistence Muster)
development
Protects design and theme files from unintended changes. Locks tailwind.config, global CSS, and theme variables. Requires explicit confirmation before modifying UI components. Activate on changes to CSS, theme config, or layout components.
tools
Proactive token budget assessment and task chunking strategy. Use this skill when queries involve multiple large file uploads, requests for comprehensive multi-document analysis, complex multi-step workflows with heavy research (10+ tool calls), phrases like "complete analysis", "full audit", "thorough review", "deep dive", or tasks combining extensive research with large output artifacts. This skill helps assess token consumption risk early and recommend chunking strategies before beginning work.
development
Erzwingt striktes Test-Driven Development mit Red-Green-Refactor Zyklus. Blockiert Code-Generierung ohne vorherige Tests. Dokumentiert 13 ungueltige Rationalisierungen. Aktivieren bei neuen Features, Bug Fixes, Refactoring.
development
Enforces TypeScript best practices when writing code. Automatically enables strict typing for TypeScript projects, prevents `any` usage, and recommends generic constraints. Activate on TS/TSX files, new features, code reviews.