// Requires test coverage for every bug fix to prevent regressions
# 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.6 matches