2.8 KiB
Testing Patterns
Only read this file when creating or modifying tests.
This project uses:
- Vitest
- Playwright browser testing
- Svelte Testing Library patterns through vitest/browser
Test Philosophy
Tests should prove behavior.
Do not write tests that only confirm implementation details.
Every test must contain meaningful assertions.
A test without assertions fails because:
expect.requireAssertions is enabled.
Test Locations
Tests are colocated with source files.
Client tests:
*.svelte.test.ts *.svelte.spec.ts
Server tests:
*.test.ts *.spec.ts
Vitest Projects
There are two test environments.
Client
Used for Svelte components.
Environment:
Playwright Chromium browser.
Used for:
- rendering
- user interaction
- form behavior
Server
Used for:
- load functions
- actions
- server utilities
Environment:
Node.
Before Each Test
Always reset mocks:
beforeEach(() => { vi.clearAllMocks(); });
Server Tests
Server route tests should cover:
- authenticated behavior
- unauthenticated behavior
- authorization rules
- successful operations
- failed operations
Mock:
- $lib/db
- authentication helpers
- external services
Prisma Mocking
Mock only the methods used.
Example:
vi.mock('$lib/db', () => ({ prisma: { proclamation: { findMany: vi.fn(), findUnique: vi.fn(), create: vi.fn(), update: vi.fn(), delete: vi.fn() } } }));
Do not create massive unused mocks.
Authentication Testing
Use:
createLocals()
Examples:
Unauthenticated:
createLocals()
Authenticated:
createLocals(mockUser() as any)
Specific roles:
createLocals( mockUser({ roleId: 4 }) as any )
Client Test Locators
Available:
getByRole getByText getByPlaceholder getByAltText getByTestId
Unavailable:
getByLabel getByDisplayValue
Role Queries
Always use exact regex names.
Preferred:
page.getByRole( 'textbox', { name: /^Name$/ } )
Avoid:
page.getByRole( 'textbox', { name: 'Name' } )
because substring matching can create strict-mode failures.
Select Testing
Because selects use selected options instead of bind:value:
const element = await page .getByRole( 'combobox', { name: /^Frequency$/ } ) .element();
expect( (element as HTMLSelectElement).value ).toBe('2');
Svelte Component Mocking
When mocking Svelte 5 components:
Use:
vi.mock('$lib/components/example.svelte', () => ({ default: ($anchor: Element) => { const div = document.createElement('div'); $anchor.replaceWith(div); } }));
Imports using mocked modules must come after vi.mock().
If variables are needed inside mocks:
Use vi.hoisted().
Test Completion Rule
After writing tests:
Run:
npm run test
If failures occur:
Fix them.
Do not report "tests added" without verifying they pass.