A comprehensive testing strategy for your Nexpo monorepo that covers database, API, and cross-platform (web & mobile) testing using Vitest and Supabase testing tools.
This plan implements a multi-layered testing approach:
- Database Layer Tests - Using Supabase CLI + pgTAP for schema, RLS policies, and SQL functions
- API Layer Tests - Using Vitest to test tRPC procedures and Supabase client operations
- Integration Tests - End-to-end tests that verify the full stack works together
- Cross-Platform Tests - Tests that work for both web (Next.js) and mobile (Expo) clients
- Prerequisites
- Test Structure
- 1. Database Tests (Supabase CLI + pgTAP)
- 2. API Tests (Vitest)
- 3. Integration Tests
- 4. Cross-Platform Tests
- Test Utilities
- Running Tests
- CI/CD Integration
- Supabase CLI (v1.11.4+) - Already installed
- Vitest - Will be installed
- React Native Testing Library - For mobile component testing
- @testing-library/react - For web component testing
- @testing-library/jest-native - Additional matchers for React Native
Ensure you have:
- Local Supabase running (
yarn supabase:start) - Test database environment configured
- Environment variables for test mode
.
├── supabase/
│ └── tests/
│ └── database/ # Database tests (pgTAP)
│ ├── schema.test.sql
│ ├── rls.test.sql
│ ├── functions.test.sql
│ └── triggers.test.sql
├── packages/
│ └── api/
│ └── src/
│ ├── __tests__/ # API tests
│ │ ├── helpers.test.ts # Unit tests for helpers
│ │ ├── trpc.test.ts # Unit tests for middleware
│ │ ├── router.test.ts # Integration tests for router
│ │ └── setup.ts
│ └── __mocks__/ # Test mocks
│ └── supabase.ts
├── apps/
│ ├── next/
│ │ └── __tests__/ # Next.js specific tests
│ │ ├── api.test.ts
│ │ └── pages.test.tsx
│ └── expo/
│ └── __tests__/ # Expo/React Native tests
│ ├── components.test.tsx
│ └── screens.test.tsx
└── __tests__/
└── integration/ # Integration tests
├── api-integration.test.ts
└── e2e.test.ts
Purpose: Test individual functions in isolation Characteristics:
- Test pure functions (no side effects)
- Mock all external dependencies
- Fast execution
- No database or network calls
- Test a single unit of functionality
Examples:
helpers.test.ts- Test helper functions (createMockUser, wait, etc.)trpc.test.ts- Test middleware logic- Utility function tests
Location: packages/api/src/__tests__/*.test.ts (unit test files)
Purpose: Test how multiple components work together Characteristics:
- Test interactions between components
- Mock external services (Supabase)
- Test complete procedures/endpoints
- May involve multiple layers
Examples:
router.test.ts- Test tRPC procedures end-to-end with mocked Supabase- API endpoint tests
- Service layer tests
Location: packages/api/src/__tests__/router.test.ts
Purpose: Test database schema, RLS, triggers, and functions directly Characteristics:
- Test at database level
- Use pgTAP framework
- Test schema structure
- Test RLS policies
- Test database functions and triggers
Examples:
schema.test.sql- Schema structure testsrls.test.sql- Row Level Security teststriggers.test.sql- Trigger tests
Location: supabase/tests/database/*.test.sql
Purpose: Test complete user flows from frontend to backend Characteristics:
- Test full stack
- Use real database (test instance)
- Test actual HTTP requests
- Test authentication flows
- Slower execution
Examples:
- Complete user registration flow
- Login and data fetching
- Error handling across layers
Location: __tests__/integration/e2e.test.ts (to be created)
Test database schema, RLS policies, triggers, and functions directly at the database level.
-
Create tests directory:
mkdir -p supabase/tests/database
-
Test files use pgTAP syntax - Supabase CLI automatically runs these tests
Tests database schema structure:
- Table existence
- Column types and constraints
- Indexes
- Foreign keys
Tests Row Level Security policies:
- Public read access
- Authenticated user insert/update/delete
- Policy application with different user contexts
Tests database triggers:
updated_attrigger functionality- Trigger execution timing
Tests database functions:
update_updated_at_column()function- Function return values
- Error handling
# Run all database tests
yarn supabase test db
# Run specific test file
supabase test db --file supabase/tests/database/schema.test.sqlTest tRPC procedures, Supabase client operations, and business logic.
-
Install Vitest and testing dependencies:
# In packages/api yarn add -D vitest @vitest/ui @vitest/coverage-v8 yarn add -D @testing-library/react @testing-library/jest-dom yarn add -D @testing-library/react-native @testing-library/jest-native -
Create Vitest config for each package/app that needs testing
- Test all tRPC procedures
- Mock Supabase client
- Test input validation (Zod schemas)
- Test error handling
- Test authentication flows
- Test Supabase client creation
- Test connection to database
- Test query operations
- Test error handling
- Test helper functions
- Test data transformations
- Test validation logic
Create a mock Supabase client for testing:
- Mock database responses
- Simulate errors
- Test different user contexts
createTestContext()- Create test tRPC contextcreateMockUser()- Create mock authenticated usersetupTestDatabase()- Setup test database state
Test the full stack: Database → API → Client
- Test tRPC procedures against real database
- Test with actual Supabase client
- Test authentication flows end-to-end
- Test RLS policies in action
- Test complete user flows
- Test web and mobile clients
- Test error scenarios
- Test performance
-
Test Database Setup:
- Use separate test database or reset before each test
- Seed test data
- Clean up after tests
-
Test Server:
- Start test Next.js server
- Start test Expo server
- Clean up after tests
Ensure API and business logic work identically on web and mobile.
-
Shared Test Suite:
- Create shared test utilities that work for both platforms
- Test tRPC client behavior on both platforms
- Test Supabase client on both platforms
-
Platform-Specific Tests:
- Web: Test Next.js specific features
- Mobile: Test Expo/React Native specific features
Tests tRPC client that works on both platforms:
- Query execution
- Mutation execution
- Error handling
- Authentication
Next.js specific tests:
- API route handlers
- Server-side rendering
- Middleware
Expo specific tests:
- Native module integration
- Platform-specific APIs
Vitest configuration for API package:
- Test environment setup
- Mock configuration
- Coverage settings
Vitest configuration for Next.js:
- React Testing Library setup
- Next.js specific mocks
Vitest configuration for Expo:
- React Native Testing Library setup
- Expo specific mocks
Shared test utilities:
- Database setup/teardown
- Mock user creation
- Test data factories
Global test setup:
- Environment variables
- Database initialization
- Mock server setup
Add to package.json:
{
"scripts": {
"test": "turbo test",
"test:db": "supabase test db",
"test:api": "vitest --run packages/api",
"test:web": "vitest --run apps/next",
"test:mobile": "vitest --run apps/expo",
"test:integration": "vitest --run __tests__/integration",
"test:watch": "vitest",
"test:coverage": "vitest --coverage"
}
}Each package/app should have its own test scripts:
{
"scripts": {
"test": "vitest --run",
"test:watch": "vitest",
"test:ui": "vitest --ui"
}
}# Run all tests
yarn test
# Run database tests only
yarn test:db
# Run API tests only
yarn test:api
# Run web tests only
yarn test:web
# Run mobile tests only
yarn test:mobile
# Run integration tests
yarn test:integration
# Watch mode (for development)
yarn test:watch
# Coverage report
yarn test:coveragename: Tests
on: [push, pull_request]
jobs:
test-db:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: supabase/setup-cli@v1
- run: yarn supabase:start
- run: yarn test:db
test-api:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 20
- run: yarn install
- run: yarn supabase:start
- run: yarn test:api
test-web:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 20
- run: yarn install
- run: yarn test:web
test-mobile:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: actions/setup-node@v3
with:
node-version: 20
- run: yarn install
- run: yarn test:mobile- Each test should be independent
- Reset database state between tests
- Clean up resources after tests
- Mock Supabase for unit tests
- Use real Supabase for integration tests
- Mock external APIs
- Use factories for test data
- Seed test database consistently
- Clean up test data
- Test error scenarios
- Test edge cases
- Test validation failures
- Test query performance
- Test API response times
- Test under load
- ✅ Create database test structure
- ✅ Set up Vitest configuration
- ✅ Create test utilities and helpers
- ✅ Write initial test suite
- ✅ Set up CI/CD integration
- ✅ Add coverage reporting
- ✅ Document test patterns