A test suite that takes 30 minutes to run is a test suite that doesn't get run. Speed isn't just nice to have - it's essential for a healthy development workflow.
When tests are slow:
// 😱 BAD: Real database for every test (500ms+ per test) test('user can update profile', async () => { await db.connect(); await db.query('INSERT INTO users ...'); await db.query('UPDATE users SET ...'); const result = await db.query('SELECT * FROM users ...'); await db.close(); expect(result.name).toBe('Alice'); }); // ✅ GOOD: In-memory test double (1ms per test) test('user can update profile', () => { const repo = new InMemoryUserRepo(); const user = repo.save({ name: 'Bob' }); repo.update(user.id, { name: 'Alice' }); expect(repo.find(user.id).name).toBe('Alice'); });
// 😱 BAD: Fixed delays (always wastes time) test('async operation completes', async () => { triggerAsync(); await sleep(2000); // Always waits 2 seconds expect(getResult()).toBe('done'); }); // ✅ GOOD: Wait for condition (only waits as long as needed) test('async operation completes', async () => { triggerAsync(); await waitFor(() => getResult() === 'done', { timeout: 2000, interval: 10 }); expect(getResult()).toBe('done'); });
// 😱 BAD: Rebuild everything for each test beforeEach(async () => { await buildDockerContainer(); await seedDatabase(); await compileAssets(); await startServers(); }); // ✅ GOOD: Share expensive setup, isolate cheap state beforeAll(async () => { // One-time expensive setup await startTestServer(); }); beforeEach(() => { // Cheap per-test isolation resetInMemoryDatabase(); clearMockCalls(); });
// Jest jest --maxWorkers=4 // Pytest pytest -n auto // Go go test -parallel 8 ./...
Database → In-memory store
HTTP calls → Mocked responses
File system → Memory filesystem
Time delays → Fake timers
// Instead of loading all fixtures const getUser = lazy(() => loadFixture('user.json')); const getOrders = lazy(() => loadFixture('orders.json')); test('user test', () => { // Only loads user fixture const user = getUser(); });
If a test exceeds these limits, it's testing at the wrong level or needs optimization.
# Find slow tests in Jest jest --listTests --findRelatedTests --json # Profile Python tests pytest --durations=10 # Go test benchmarks go test -bench=. -benchtime=10s # Track test time trends in CI - name: Run tests with timing run: | START=$(date +%s) npm test END=$(date +%s) echo "Tests took $((END-START)) seconds"