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"