# Testing Guide Comprehensive testing strategy for MotoVaultPro Modified Feature Capsule architecture. ## Testing Philosophy Each feature capsule contains complete, isolated test suites with no cross-feature dependencies. ## Test Structure ### Per Feature Organization ``` backend/src/features/[name]/tests/ ├── fixtures/ # Test data ├── unit/ # Isolated unit tests │ ├── [name].service.test.ts │ └── [external].client.test.ts └── integration/ # Full API tests └── [name].integration.test.ts ``` ## Docker Testing Workflow ### Backend Testing ```bash # Enter backend container shell make shell-backend # Inside container: # Test all features npm test # Test single feature (complete isolation) npm test -- --testPathPattern=src/features/vehicles # Test specific test type npm test -- --testPathPattern=src/features/vehicles/tests/unit npm test -- --testPathPattern=src/features/vehicles/tests/integration # Test with coverage npm test -- --testPathPattern=src/features/vehicles --coverage # Watch mode npm run test:watch ``` ### Frontend Testing ```bash # From project root, run tests in frontend container docker compose exec mvp-frontend npm test # Watch mode docker compose exec mvp-frontend npm run test:watch # With coverage docker compose exec mvp-frontend npm test -- --coverage ``` ### Test Environment Setup 1. **Container-Based**: All tests run inside Docker containers 2. **Database**: Uses the development database in the stack (`motovaultpro`) 3. **Mock External APIs**: No real API calls during testing (where implemented) 4. **Cleanup**: Prefer transactions/cleanup per test; see feature tests for patterns ## Test Types ### Unit Tests **Location**: `features/[name]/tests/unit/` **Purpose**: Test business logic in isolation **Mocking**: All external dependencies mocked Example: `vehicles.service.test.ts` - Tests VIN validation logic - Tests vehicle creation with mocked vPIC responses - Tests caching behavior with mocked Redis - Tests error handling paths ### Integration Tests **Location**: `features/[name]/tests/integration/` **Purpose**: Test complete API workflows **Database**: Real test database with transactions Example: `vehicles.integration.test.ts` - Tests complete POST /api/vehicles workflow - Tests authentication middleware - Tests database persistence - Tests error responses ### Test Data **Location**: Inline within test files **Purpose**: Test-specific mock data **Format**: TypeScript objects defined in test files Tests use inline mock data rather than external fixture files. Example pattern: ```typescript const mockVehicle = { vin: "1HGBH41JXMN109186", nickname: "Test Honda", color: "Blue" }; const mockPlatformResponse = { make: "Honda", model: "Civic", year: 2021 }; ``` ## Testing Commands Reference ### Development Testing ```bash # Enter backend container make shell-backend # Run all tests npm test # Run specific feature npm test -- --testPathPattern=src/features/vehicles npm test -- --testPathPattern=src/features/fuel-logs npm test -- --testPathPattern=src/features/maintenance npm test -- --testPathPattern=src/features/stations # Run with file watching npm run test:watch # Run single test file npm test -- vehicles.service.test.ts # Run tests matching pattern npm test -- --testNamePattern="VIN validation" # Frontend tests (Jest) docker compose exec mvp-frontend npm test ``` ### Coverage Reports ```bash # Generate coverage for specific feature npm test -- --testPathPattern=src/features/vehicles --coverage # View coverage report # Inside the container, open using your OS tooling, # or copy the report out of the container as needed ``` ### Container Management ```bash # Restart containers with fresh database make rebuild # View test logs make logs-backend # Clean all test data make clean && make start ``` ## Test Configuration ### Jest Configuration - Backend: `backend/jest.config.js` - Frontend: `frontend/jest.config.ts` - React + TypeScript via `ts-jest` - jsdom environment - Testing Library setup in `frontend/setupTests.ts` ### Database Testing - **DB**: Same as development (`motovaultpro`) within Docker - **Transactions**: Recommended pattern is one transaction per test - **Isolation**: Keep tests independent; avoid shared state - **Seeding**: Use feature-level fixtures when needed ### Coverage and Availability All 15 features have test suites with unit and/or integration tests: - `admin` - Unit + integration tests - `auth` - Unit + integration tests - `backup` - Unit + integration tests - `documents` - Unit + integration tests - `fuel-logs` - Unit + integration tests - `maintenance` - Unit + integration tests - `notifications` - Unit + integration tests - `onboarding` - Unit tests - `platform` - Unit + integration tests - `stations` - Unit + integration tests (including community stations) - `terms-agreement` - Unit tests - `user-export` - Unit tests - `user-preferences` - Unit tests - `user-profile` - Unit + integration tests - `vehicles` - Unit + integration tests ### Mock Strategy - **External APIs**: Completely mocked (vPIC, Google Maps) - **Database**: Real database with transactions - **Redis**: Mocked for unit tests, real for integration - **Auth**: Mocked JWT tokens for protected endpoints ## Test Data Management ### Inline Mock Data Strategy ```typescript // In test files - define mock data inline const mockVehicle = { vin: '1HGBH41JXMN109186', nickname: 'Test Honda', year: 2021, make: 'Honda', model: 'Civic' }; describe('Vehicle Service', () => { it('should create vehicle', async () => { const result = await vehicleService.create(mockVehicle, 'user123'); expect(result.make).toBe('Honda'); }); }); ``` ### Database Seeding ```javascript beforeEach(async () => { // Clean slate for each test await db.query('TRUNCATE TABLE vehicles CASCADE'); // Insert test-specific data await db.query('INSERT INTO vehicles ...', testData); }); ``` ## Debugging Tests ### Debug Single Test ```bash # Run specific test with debugging npm test -- --testNamePattern="should create vehicle" --verbose # Debug integration test npm test -- features/vehicles/tests/integration --detectOpenHandles ``` ### Common Issues #### Container Connection Issues ```bash # Check container health make logs-backend # Restart with fresh state make rebuild ``` #### Database Connection Issues ```bash # Check postgres container docker compose logs postgres # Reset database make clean && make start ``` #### Test Timeout Issues ```bash # Increase timeout in jest config # Or debug hanging connections npm test -- --detectOpenHandles ``` ## Continuous Integration ### Pre-commit Testing All tests must pass before commits: ```bash # Backend: Enter shell and run tests make shell-backend npm run lint npm test # Frontend: Run tests from project root docker compose exec mvp-frontend npm run lint docker compose exec mvp-frontend npm test ``` ### Feature Development Workflow 1. **Write tests first**: TDD approach preferred 2. **Run tests continuously**: Use `npm run test:watch` 3. **Test in containers**: Always verify with `docker compose exec mvp-backend npm test` 4. **Check coverage**: Ensure new code is covered 5. **Integration last**: Run full test suite before PR ## Test Performance ### Parallel Execution - Jest runs tests in parallel by default - Feature isolation allows true parallel testing - No shared state between feature tests ### Test Speed Optimization - **Unit tests**: Fast (< 1 second per test) - **Integration tests**: Medium (< 5 seconds per test) - **Full suite**: Target < 30 seconds total ### Database Optimization - Use transactions for rollback (faster than truncate) - Minimal fixture data - Avoid complex joins in test setup ## Error Testing Strategy ### Expected Error Cases ```javascript describe('Error Handling', () => { it('should handle invalid VIN', async () => { await expect( vehicleService.create({ vin: 'INVALID' }, 'user123') ).rejects.toThrow('Invalid VIN format'); }); it('should handle vPIC API failure', async () => { mockVpicClient.decode.mockRejectedValue(new Error('API down')); const result = await vehicleService.create(validVehicle, 'user123'); expect(result.make).toBeNull(); // Graceful degradation }); }); ``` ### External Service Failures - Mock API failures to test error handling - Test timeout scenarios - Test network connectivity issues - Verify graceful degradation paths