Claude Skills Guide

Claude Code for Flaky Test Detection and Fix Guide

Flaky tests are one of the most frustrating problems in software development. They pass and fail intermittently, eroding trust in your test suite and wasting developer time. This guide shows you how to use Claude Code to detect, diagnose, and fix flaky tests effectively.

Understanding Flaky Tests

A flaky test is one that produces different results when run multiple times without any code changes. These tests undermine confidence in continuous integration and can mask real regressions. Common causes include:

Claude Code can help you identify these patterns and provide actionable fixes.

Detecting Flaky Tests with Claude Code

The first step is identifying which tests are flaky. Claude Code can analyze your test suite and detect common flakiness patterns.

Analyzing Test Files

Ask Claude to examine your test files for known flaky patterns:

Look through my test files in the tests/ directory and identify any patterns that commonly cause flakiness: 
- Tests that don't properly clean up shared state
- Tests with hardcoded timeouts that may be too short
- Tests that depend on external services without mocking
- Tests that assume specific ordering of async operations

Claude will analyze your codebase and provide specific file locations and line numbers where issues exist.

Running Iterations to Find Flakiness

For tests you suspect are flaky, run them multiple times:

# Run a specific test 10 times to detect flakiness
for i in {1..10}; do 
    pytest -xvs tests/test_api.py::test_user_login || echo "FAILED on iteration $i"
done

Ask Claude to analyze the output and identify which tests fail intermittently and what patterns they share.

Diagnosing Root Causes

Once you’ve identified flaky tests, Claude Code can help diagnose the root cause.

Analyzing Test Output

Provide Claude with the failing test output and ask for analysis:

This test fails intermittently. Here's the error from the last failure:
[paste error output]

And here's the passing test output:
[paste passing output]

What are the differences? What could cause intermittent failures?

Claude will identify timing issues, race conditions, or state leakage that might not be obvious.

Examining Async Code

Flaky tests often involve async operations. Ask Claude to review async test code:

Review this test and identify potential race conditions or timing issues:
[paste test code]

Suggest specific fixes with code changes.

Claude can recommend adding proper waits, using fixtures for cleanup, or restructuring async assertions.

Fixing Flaky Tests

Claude Code provides actionable fixes for common flaky test patterns.

Fixing Shared State Issues

When tests share state, they can interfere with each other:

# BEFORE: Flaky test with shared state
class TestUser:
    def setup_method(self):
        self.user = User.get_default()  # Shared across tests!
    
    def test_user_name(self):
        assert self.user.name == "expected"
    
    def test_user_email(self):
        assert self.user.email == "expected"  # May fail if previous test modified user
# AFTER: Fixed with proper isolation
class TestUser:
    @pytest.fixture
    def fresh_user(self):
        return User.create(name="test", email="test@example.com")
    
    def test_user_name(self, fresh_user):
        assert fresh_user.name == "expected"
    
    def test_user_email(self, fresh_user):
        assert fresh_user.email == "expected"

Ask Claude to refactor your tests with proper fixtures and cleanup.

Fixing Race Conditions

For tests with timing issues:

// BEFORE: Flaky async test
test('user data loads', async () => {
  loadUserData();
  expect(userData.name).toBe('John'); // May run before data loads
});

// AFTER: Fixed with proper waiting
test('user data loads', async () => {
  await loadUserData();
  expect(userData.name).toBe('John');
});

Fixing Time-Dependent Tests

Tests that depend on current time or dates are inherently flaky:

# BEFORE: Time-dependent test
def test_subscription_active():
    subscription = Subscription(created_at=datetime.now())
    assert subscription.is_active()  # Fails if run near midnight

# AFTER: Fixed with time injection
from freezegun import freeze_time

@freeze_time("2026-01-15 12:00:00")
def test_subscription_active():
    subscription = Subscription(created_at=datetime.now())
    assert subscription.is_active()

Ask Claude to identify time dependencies and suggest appropriate fixes.

Preventing Future Flakiness

Beyond fixing existing flaky tests, Claude Code can help you prevent new ones.

Adding Test Reliability Checks

Ask Claude to review your test suite and recommend reliability improvements:

Review my test suite and suggest:
1. Which tests should have retry logic for known flakiness
2. Appropriate timeouts for async operations
3. Proper cleanup in fixtures
4. Mocking strategies for external dependencies

Implementing Test Health Monitoring

Consider adding logging to track flaky tests over time:

import logging
import time

def track_test_flakiness(test_name, func, *args, **kwargs):
    """Wrapper to track test reliability."""
    start = time.time()
    attempt = 0
    max_attempts = 3
    
    while attempt < max_attempts:
        try:
            result = func(*args, **kwargs)
            logging.info(f"Test {test_name} passed on attempt {attempt + 1}")
            return result
        except AssertionError as e:
            attempt += 1
            if attempt == max_attempts:
                logging.error(f"Test {test_name} failed after {max_attempts} attempts")
                raise
    
    return result

Best Practices for Test Reliability

Follow these guidelines to minimize flaky tests:

  1. Isolate tests completely - Each test should set up its own data and clean up after itself
  2. Mock external dependencies - Network calls, databases, and file systems should be mocked in tests
  3. Avoid timing assumptions - Use proper async/await patterns instead of sleep()
  4. Use deterministic data - Avoid random values or time-dependent assertions
  5. Run tests in isolation - Configure your test runner to run tests in random order

Conclusion

Flaky tests don’t have to plague your development workflow. By using Claude Code to detect, diagnose, and fix flaky tests, you can build a more reliable test suite. Start by identifying your flakiest tests, apply the fixes suggested in this guide, and implement prevention strategies to maintain test reliability over time.

Remember that fixing flaky tests is an iterative process. Run your tests multiple times after making changes, monitor for new flakiness, and continuously improve your test isolation patterns.

Built by theluckystrike — More at zovo.one