This document outlines the improvements made to fix E2E test flakiness and add robust retry mechanisms.
- Increased timeout from 30s to 60s for complex operations
- Added custom test environment with proper setup/teardown
- Implemented custom test sequencer for stable test ordering
- Added flakiness detection reporter to identify unstable tests
- Exponential backoff retry logic with configurable parameters
- Smart retry conditions (don't retry on 4xx errors, retry on network issues)
- Wait utilities for stable conditions and value stabilization
- Timeout handling with proper error propagation
- Built-in retry logic for HTTP requests
- Timeout management with configurable limits
- Connection pooling awareness for database operations
- Endpoint readiness checks with polling
- Connection stability checks before test execution
- Automatic cleanup between test runs
- Transaction rollback for failed tests
- Connection pooling management
- Environment variable management for test isolation
- Resource cleanup after each test run
- Database readiness verification
- External service mocking configuration
- Automated flakiness reporting during test runs
- Failure rate analysis across multiple test executions
- Detailed failure pattern identification
- Recommendations for fixing flaky tests
npm run test:e2e# Quick stability check (3 runs)
npm run test:e2e:stability:quick
# Full stability analysis (5 runs)
npm run test:e2e:stability
# Auth-specific stability test
npm run test:e2e:stability:auth
# Extended flakiness detection (10 runs)
npm run test:e2e:flaky# Test specific pattern with custom runs
node test/utils/e2e-test-runner.js --pattern "auth.e2e-spec.ts" --runs 8
# Parallel execution (if supported)
node test/utils/e2e-test-runner.js --runs 5 --parallelit('should register user', async () => {
const response = await request(app.getHttpServer())
.post('/api/auth/register')
.send(userData);
expect(response.status).toBe(201);
});it('should register user successfully with retries', async () => {
await retryHelper.withRetry(
async () => {
const response = await httpClient.post('/api/auth/register', userData);
expect(response.status).toBe(201);
expect(response.body).toHaveProperty('user');
},
{
maxAttempts: 3,
delayMs: 1000,
backoffMultiplier: 2,
},
);
}, 30000);The system automatically detects flaky tests based on:
- Failure rate threshold: 10% or higher
- Minimum runs: At least 3 executions
- Pattern analysis: Consistent failure patterns
🧪 Running E2E stability test with 5 iterations...
🏃 Run 1/5 starting...
✅ Run 1/5 completed: 8/8 tests passed
🏃 Run 2/5 starting...
✅ Run 2/5 completed: 8/8 tests passed
❌ Run 3/5 completed: 7/8 tests passed
❌ Failed tests: should handle concurrent requests
📊 Stability report saved to: ./test-results/e2e-stability-report-2024-01-15T10-30-00.md
await retryHelper.withRetry(
() => httpClient.get('/api/data'),
{ maxAttempts: 3, delayMs: 500 }
);await retryHelper.waitFor(
() => checkDatabaseReady(),
{ timeout: 10000, description: 'database readiness' }
);await retryHelper.waitForStable(
() => getQueueLength(),
{ stabilityWindowMs: 1000, checkIntervalMs: 100 }
);it('should complete operation', async () => {
// Test logic with explicit timeout
}, 30000);beforeEach(async () => {
await testDb.clean();
});- Flakiness reports are generated automatically
- Test stability metrics are tracked
- Recommendations are provided for fixing issues
# In GitHub Actions
- name: Run E2E Stability Tests
run: npm run test:e2e:stability
continue-on-error: false
- name: Generate Flakiness Report
run: npm run test:e2e:flaky
if: failure()- Race conditions in async operations
- Database connection issues
- External service dependencies
- Timing-sensitive assertions
- Resource cleanup problems
- Run stability tests multiple times
- Check flakiness reports for patterns
- Add detailed logging
- Use retry helpers with verbose output
- Isolate problematic test cases
- Retry logic adds minimal overhead (~100ms per retry)
- Stability checks ensure reliable test execution
- Parallel execution available for faster feedback
- Resource cleanup prevents test interference
- Machine learning-based flakiness prediction
- Automatic test quarantine for flaky tests
- Performance regression detection
- Cross-environment stability validation