E2e and unit tests
Your project includes a complete testing setup with Vitest for unit tests and Playwright for end-to-end tests. Both are pre-configured with test utilities, factories, and database helpers.
Unit tests (Vitest)
Running
pnpm test # Run once
pnpm test:watch # Watch mode
pnpm test:ui # Vitest UI in browser
pnpm test:coverage # With coverage reportConfiguration
Tests are configured in packages/backend/vitest.config.ts:
- Test files:
src/**/*.{test,spec}.ts(colocated with source) - Excludes
__e2e__directories - Single-threaded execution to avoid DB conflicts
- 30-second timeout per test
- Coverage via V8 provider
Writing a unit test
Create a test file in __tests__/ next to the source, named after the controller:
import { describe, it, expect } from 'vitest';
import { createAuthenticatedContext } from '../../../test/testUtils';
import { createTestUserWithOrganization } from '../../../test/testFactories';
describe('EntityCreateController', () => {
it('should create an entity', async () => {
const { user, organization, member } =
await createTestUserWithOrganization();
const context = createAuthenticatedContext(user, organization, member);
const result = await entityCreateController({ name: 'Test' }, context);
expect(result).toBeDefined();
expect(result.name).toBe('Test');
});
});Test utilities
| Utility | Purpose |
|---|---|
createMockContext() | Mock unauthenticated context |
createAuthenticatedContext() | Mock authenticated context |
createTestUserWithOrganization() | Create user + organization + member |
createTestApiKey() | Create test API key |
createTestAuditLog() | Create test audit log entry |
testPrismaClient() | Prisma client bypassing RLS |
cleanTestDatabase() | Fast table truncation between tests |
Test categories
Tests are organized by type:
- Controller tests: Test API controllers with mocked auth context
- Schema tests: Validate Zod schemas with edge cases
- Utility tests: Test pure functions in isolation
- Integration tests: Test database operations with real Prisma client
E2e tests (Playwright)
Running
pnpm test:e2e # Run headless
pnpm test:e2e:ui # Playwright UI
pnpm test:e2e:headed # With visible browserConfiguration
Tests are configured in packages/backend/playwright.config.ts:
- Test files:
src/**/__e2e__/**/*.spec.ts - Serial execution (single worker) to avoid DB conflicts
- 30-second timeout per test, 10-second for assertions
- Automatic server startup (backend on
:3011, frontend on:5173) - Uses
.env.testfor configuration
Writing an E2e test
Create a test file in __e2e__/ inside the feature directory, named after the page:
import { test, expect } from '@playwright/test';
import { cleanTestDatabase } from '../../../test/testPrismaClient';
import { signUpAndSignIn } from '../../../test/testE2eHelpers';
test.describe('Feature page', () => {
test.beforeEach(async () => {
await cleanTestDatabase();
});
test('page loads', async ({ page }) => {
await signUpAndSignIn(page);
await page.goto('/feature');
await expect(page.getByTestId('page-header-title')).toBeVisible();
});
});E2e test categories
Tests cover all major features:
- Authentication: Sign in/up, password reset, email verification
- CRUD operations: Create, read, update, delete flows
- Forms: Validation, submission, error handling
- Data tables: Filtering, sorting, pagination
- API keys: List, create, edit
- Audit logs: Log viewer
- Subscriptions: Stripe checkout
- Multi-tenancy: Organization switching, member invitations
Best practices
- Use
cleanTestDatabase()inbeforeEachfor test isolation - Use
data-testidattributes for reliable element selection in E2E tests - Always read
schema.prismabefore creating test data to match required fields - Use
Number(value)when comparing PrismaDecimalfields - Run tests serially to avoid database race conditions
Key files
| File | Description |
|---|---|
backend/vitest.config.ts | Vitest configuration |
backend/playwright.config.ts | Playwright configuration |
backend/src/test/testUtils.ts | Mock context utilities |
backend/src/test/testFactories.ts | Test data factories |
backend/src/test/testPrismaClient.ts | Test database client + cleanup |
backend/src/test/testE2eHelpers.ts | E2E sign up/sign in helper |