Always Add Tests for Bug Fixes

// Requires test coverage for every bug fix to prevent regressions

TestingBest PracticesCode Quality
Highly Rated
Community Verified

// detailed.guidelines

# Always Add Tests for Bug Fixes

If it broke once, it will break again. Tests prevent regressions.

## The Rule

Every bug fix MUST include:
1. A test that reproduces the bug
2. Proof that the test fails before the fix
3. Proof that the test passes after the fix

## Why This Matters

- **Prevents regressions:** Bug won't return in future changes
- **Documents the bug:** Test explains what went wrong
- **Verifies the fix:** Confirms the solution actually works
- **Improves coverage:** Fills gaps in existing tests

## Test-First Approach

### Step 1: Write Failing Test
```javascript
// First, capture the bug
test('should not crash on empty array', () => {
  const result = calculateAverage([]); // This currently crashes
  expect(result).toBe(0);
});
// ❌ Test fails - reproduces the bug
```

### Step 2: Fix the Code
```javascript
function calculateAverage(numbers) {
  // FIX: Handle empty array
  if (numbers.length === 0) return 0;
  
  return numbers.reduce((a, b) => a + b) / numbers.length;
}
```

### Step 3: Verify Test Passes
```javascript
test('should not crash on empty array', () => {
  const result = calculateAverage([]);
  expect(result).toBe(0);
});
// ✅ Test passes - bug is fixed
```

## What to Test

### The Exact Scenario
Test the specific case that caused the bug.

```javascript
// Bug: App crashed when user.profile was null
test('handles missing profile gracefully', () => {
  const user = { id: 1, profile: null };
  expect(() => renderUser(user)).not.toThrow();
});
```

### Edge Cases Nearby
Test related edge cases that might have similar issues.

```javascript
test('handles undefined profile', () => {
  const user = { id: 1 };
  expect(() => renderUser(user)).not.toThrow();
});

test('handles empty profile object', () => {
  const user = { id: 1, profile: {} };
  expect(() => renderUser(user)).not.toThrow();
});
```

## PR Checklist for Bug Fixes

- [ ] Test reproduces the original bug
- [ ] Test would fail without the fix
- [ ] Test passes with the fix
- [ ] Edge cases are covered
- [ ] Test has clear description of the bug
- [ ] Regression test is marked as such

## Test Naming Convention

Make it obvious these are regression tests:

```javascript
// ✅ Good names
test('regression: handles null user profile without crashing')
test('fixes #123: validates email before sending')
test('bug fix: prevents duplicate order submissions')

// ❌ Vague names
test('it works')
test('email validation')
test('order test')
```

## Example PR Description

```markdown
## Bug Fix: Null Profile Crash

### Problem
App crashed with "Cannot read property 'name' of null" when 
user.profile was null.

### Solution
Added null check before accessing profile properties.

### Tests Added
- ✅ Test with null profile (reproduces bug)
- ✅ Test with undefined profile (edge case)
- ✅ Test with valid profile (happy path)

All tests fail before fix, pass after.
```

## Exceptions

Only skip tests if:
- Fixing typos in documentation
- Updating dependencies with no code changes
- Emergency hotfix (must add test in follow-up PR)

## Benefits

- **Confidence:** Know the bug is really fixed
- **Documentation:** Tests explain the bug better than comments
- **Prevention:** Stop the same bug from returning
- **Quality:** Incrementally improve test coverage

No test = the bug will probably come back.