Original Issue: Performance tests were conditionally skipped in CI environments using test.skip, which undermined their core value.
Why This Was Wrong:
// Always test that the feature works correctly
expect(element.textContent).toBe("expected value");
This is the most important test - performance is secondary to correctness.
// Compare against baseline, not absolute timing
const ratio = testTime / baselineTime;
expect(ratio <= maxRatio).toBe(true);
Environment-agnostic approach that works on any hardware.
// Adjust expectations, don't skip tests
maxRatio: isCI ? 50 : (isDebugMode ? 30 : 15)
More lenient in CI, but still catches major regressions.
// Multiple iterations + warmup + median for stability
const iterations = Math.max(PERF_CONFIG.iterations, PERF_CONFIG.minIterations);
// Warmup run to reduce JIT effects
testFn();
// Use median instead of average for outlier resistance
const medianTime = times.sort()[Math.floor(times.length / 2)];
console.log(`Test=${medianTime.toFixed(2)}ms, Baseline=${baselineTime.toFixed(2)}ms, Ratio=${ratio.toFixed(2)} (max: ${maxRatio})`);
Always visible results for debugging performance issues.
Local Development:
Rapid Updates: Test=0.22ms, Baseline=0.04ms, Ratio=5.17 (max: 30) ✓
CI Environment:
Rapid Updates: Test=0.21ms, Baseline=0.04ms, Ratio=5.17 (max: 50) ✓
Same performance, different thresholds, consistent coverage.
Performance tests should never be skipped. If the environment is unreliable for timing, adjust expectations, not coverage.
This ensures you catch real performance regressions while maintaining reliable CI/CD pipelines.