Source:
ocean/docs/adr/014-cloud-first-testing-strategy.md| ✏️ Edit on GitHub
ADR-014: Cloud-First Testing Strategy
Status
Accepted
Context
Our development approach is cloud-first, using remote Supabase instances and cloud services rather than local development environments. However, our test suite was built with assumptions about local services (local Supabase, localhost:54321) that don't align with this approach.
Problems with the current testing approach:
- Tests fail when local Supabase isn't running
- Mock environments don't catch real integration issues
- Local testing can't replicate cloud-specific problems (rate limits, auth flows, network latency)
- Tests that run full builds are resource-intensive and slow
- Environment-specific bugs only appear in production
Decision
We are adopting a cloud-first testing strategy that aligns with our cloud-first development approach:
1. Test Categories
Keep Locally (Fast, Pure Tests)
- Static code analysis (security checks, code quality)
- Pure function tests (no external dependencies)
- Component logic tests with properly mocked dependencies
Move to CI/CD (Integration Tests)
- Tests requiring real services (Supabase, Stripe, etc.)
- Build validation and bundle size checks
- E2E tests against preview deployments
- Smoke tests after deployments
2. Testing Infrastructure
Local Development
- Pre-commit hooks run only static analysis
- Unit tests mock at the module boundary
- No dependency on local services
CI/CD Pipeline
- GitHub Actions run integration tests against test Supabase project
- Preview deployments get full E2E test suite
- Production deployments trigger smoke tests
- Synthetic monitoring for continuous validation
3. Implementation Changes
Removed Tests
tests/graphql-signup.test.ts- Required Supabase instancetests/pre-push/build-integrity.test.ts- Ran full build process- Exec calls in
deployment-readiness.test.ts- Ran lint/format/typecheck
Modified Tests
- JWT verifier test - Mock at module boundary to avoid URL creation
- Deployment readiness - Keep static checks, remove dynamic validations
New Approach
- Contract testing with recorded API responses
- Feature flag testing in production with PostHog
- Synthetic monitoring with real user flows
Consequences
Positive
- Tests align with actual infrastructure
- Catch real integration issues early
- Faster local development (no service dependencies)
- More reliable test results
- Better coverage of cloud-specific scenarios
Negative
- Can't run full test suite locally
- Dependency on CI/CD for integration testing
- Need proper test data management in cloud
- Potential for higher cloud service costs
Mitigation
- Use GitHub Codespaces for full environment testing
- Implement proper test data cleanup
- Monitor test environment costs
- Use Supabase branching for isolated test environments
Implementation Guidelines
For Developers
-
Writing Tests
- Mock external services at the module boundary
- No hardcoded URLs or localhost references
- Use environment variables for configuration
-
Running Tests
# Local - only unit tests
pnpm test
# CI/CD - full suite including integration
# Automatically run on PR -
Test Data
- Use unique identifiers for test data
- Implement cleanup in test teardown
- Never use production data
For CI/CD
-
PR Checks
- Static analysis and unit tests
- Deploy preview with Supabase branch
- Run E2E tests against preview
-
Main Branch
- All PR checks plus integration tests
- Deploy to staging (when available)
- Run smoke tests
-
Production
- Synthetic monitoring
- Feature flag testing
- Real user monitoring
Tools and Services
- Local: Vitest for unit tests
- E2E: Playwright (future)
- Monitoring: Checkly or Datadog Synthetics (future)
- API Testing: MSW for contract testing (future)
- Feature Flags: PostHog
Migration Path
- ✅ Remove tests requiring local services
- ✅ Update remaining tests to mock properly
- ⏳ Add E2E tests in CI/CD pipeline
- ⏳ Implement synthetic monitoring
- ⏳ Add contract testing for APIs