Test Fixing
Systematically identify and fix all failing tests using smart error grouping, root-cause analysis, and iterative validation. Avoid the "whack-a-mole" approach: group failures, fix root causes once, and verify each group before moving on.
When to Use
- User explicitly asks to fix tests: "fix these tests", "make tests pass", "get the suite green"
- User reports test failures: "tests are failing", "test suite is broken", "CI is red"
- Implementation is complete and the user wants tests passing before commit
- CI/CD pipeline failures caused by test regressions
- After a major refactor where multiple tests are broken simultaneously
- After dependency upgrades that may have introduced breaking changes
Prerequisites
- The project has an existing test suite (pytest, unittest, jest, etc.)
- A working test runner is available (
make test, uv run pytest, npm test, etc.)
- On Windows host (PowerShell), prefer
uv run pytest or the project's configured runner. If make is unavailable, invoke the runner directly.
- Check for a
CLAUDE.md, CONTRIBUTING.md, or project style guide before making edits. Adhere to project-specific coding standards.
- If the project uses
references/ or scripts/ directories, load them as needed (see Procedure).
Procedure
1. Initial Test Run — Identify Scope
Run the project's primary test command to capture the full failure surface.
Windows (PowerShell):
uv run pytest --tb=short -q
If a Makefile is present:
make test
Analyze the output for:
- Total number of failures vs. errors (they have different root causes).
- Common error patterns (repeated tracebacks, shared import lines).
- Affected modules, files, and specific test cases.
- Environment-related failures (missing env vars, missing config files, port conflicts).
- Skipped (
SKIPPED) or expected-fail (XFAIL) tests — investigate why before ignoring.
Capture the list of failing test node IDs for targeted re-runs:
uv run pytest --tb=line -q 2>&1 | Select-String "FAILED"
2. Smart Error Grouping
Group failures to solve root causes once rather than fixing symptoms one by one.
Group by:
- Error Type:
ImportError, ModuleNotFoundError, AttributeError, TypeError, AssertionError, TimeoutError.
- Location: Failures concentrated in a specific module, directory, or test file.
- Root Cause: API breaking changes, dependency updates, configuration drift, fixture issues, environment mismatches.
Prioritize groups by:
- Impact — Fix the error causing the most failures first.
- Dependency Order — Fix infrastructure/setup failures before business logic failures. A single
ImportError can cascade into dozens of downstream failures.
3. Fix Order Strategy
Follow this hierarchy to ensure a stable foundation before addressing higher-level logic:
Level 1 — Infrastructure & Environment
ImportError, ModuleNotFoundError
- Missing dependencies or incorrect
pyproject.toml / requirements.txt
- Environment variable or configuration mismatches
- Fixture setup/teardown failures
- Database or service connection errors
Level 2 — Interface & API Changes
- Function signature mismatches (
TypeError)
- Renamed methods or moved modules (
AttributeError)
- Updated return types or data structures (e.g.,
dict → dataclass)
- Changed CLI flags or API response shapes
Level 3 — Logic & Behavioral Issues
AssertionError (incorrect values)
- Edge case failures (empty input, boundary values, timezone issues)
- Race conditions or timeout issues
- Flaky tests (intermittent failures)
4. Systematic Fixing Process (Per Group)
For each group, starting with the highest priority:
4a. Identify Root Cause
4b. Implement Fix
- Apply targeted, minimal changes using the Edit tool.
- Adhere to project-specific coding standards (refer to
CLAUDE.md or equivalent).
- Keep changes minimal to avoid introducing new regressions.
- If a
scripts/ directory contains helper scripts (e.g., lint, format, type-check), run them after each fix to catch side effects early.
4c. Verify Fix (Iterative Validation)
Run only the affected subset of tests to save time and reduce noise.
# Run a specific test file
uv run pytest tests/path/to/test_file.py -v
# Run tests matching a specific keyword/pattern
uv run pytest -k "keyword" -v
# Run only failing tests from the last run
uv run pytest --lf -v
# Run a single test node ID
uv run pytest tests/path/to/test_file.py::TestClass::test_method -v
# Extra verbose output for deep debugging
uv run pytest tests/path/to/test_file.py -vv --tb=long
Ensure the current group passes completely before moving to the next group.
4d. Move to Next Group
Repeat 4a–4c for the next priority group.
5. Final Verification
Once all groups are addressed:
# Run the complete test suite
uv run pytest --tb=short
# Or via Makefile
make test
Pitfalls
- Do not ignore
SKIPPED or XFAIL tests without investigating why they are skipped — they may mask real failures.
- Do not modify the test suite to match incorrect behavior in the code. If the test is wrong, confirm the expected behavior first, then update the test with a clear reason.
- Do not use
pytest.mark.skip as a temporary fix without a corresponding TODO comment or ticket reference.
- Do not perform bulk "find and replace" across the codebase without verifying the impact on all affected tests.
- Do not comment out failing tests or weaken assertions just to make the suite pass.
- Do not fix symptoms individually ("whack-a-mole") — always group and address root causes.
- Do not run the full suite after every single change — use targeted subset runs to maintain a fast feedback loop.
- Do not forget to remove debug
print() statements or temporary logging added during investigation.
- Do not commit fixes for multiple unrelated groups in a single atomic commit if the project expects granular history — prefer one commit per root-cause group.
- Watch for flaky tests: if a test passes on re-run but failed initially, investigate race conditions, time-dependent logic, or shared mutable state before dismissing it.
- Watch for environment drift: failures that only appear in CI but not locally often indicate missing env vars, different Python/Node versions, or OS-specific path handling (especially Windows vs. Linux path separators).
Verification
Confirm each item before declaring the task complete:
Examples
Scenario: User reports "The tests are failing after my refactor."
- Run:
uv run pytest --tb=short -q → 15 failures.
- Group:
- 8 ×
ImportError → Root: utils.py moved to core/utils.py.
- 5 ×
AttributeError → Root: get_user() now returns a User object instead of a dict.
- 2 ×
AssertionError → Root: Logic bug in date calculation.
- Fix Group 1 (Infrastructure): Update imports across affected files → Run
uv run pytest tests/test_utils.py -v → Pass.
- Fix Group 2 (Interface): Update call sites to access object attributes (
user.name instead of user["name"]) → Run uv run pytest tests/test_users.py -v → Pass.
- Fix Group 3 (Logic): Correct date calculation edge case → Run
uv run pytest tests/test_dates.py -v → Pass.
- Final: Run
uv run pytest --tb=short → All pass ✓.
Related Skills
debugging — General debugging workflows for non-test-specific failures.
code-review — Reviewing fixes before commit to ensure minimal, standards-compliant changes.
refactoring — Safe refactoring practices that minimize test breakage.
1---2name: test-fixing3description: Groups failing suite errors by type and root cause, then repairs infrastructure, API drift, and assertion bugs until the project's runner is green. Use when tests fail, CI is red, or a refactor broke the suite. Do not use to author a new pytest or TestNG tree, or to skip or weaken assertions for a pass.4---5
6# Test Fixing
7
8Systematically identify and fix all failing tests using smart error grouping, root-cause analysis, and iterative validation. Avoid the "whack-a-mole" approach: group failures, fix root causes once, and verify each group before moving on.
9
10## When to Use
11
12- User explicitly asks to fix tests: "fix these tests", "make tests pass", "get the suite green"
13- User reports test failures: "tests are failing", "test suite is broken", "CI is red"
14- Implementation is complete and the user wants tests passing before commit
15- CI/CD pipeline failures caused by test regressions
16- After a major refactor where multiple tests are broken simultaneously
17- After dependency upgrades that may have introduced breaking changes
18
19## Prerequisites
20
21- The project has an existing test suite (pytest, unittest, jest, etc.)
22- A working test runner is available (`make test`, `uv run pytest`, `npm test`, etc.)
23- On Windows host (PowerShell), prefer `uv run pytest` or the project's configured runner. If `make` is unavailable, invoke the runner directly.
24- Check for a `CLAUDE.md`, `CONTRIBUTING.md`, or project style guide before making edits. Adhere to project-specific coding standards.
25- If the project uses `references/` or `scripts/` directories, load them as needed (see Procedure).
26
27## Procedure
28
29### 1. Initial Test Run — Identify Scope
30
31Run the project's primary test command to capture the full failure surface.
32
33**Windows (PowerShell):**
34```powershell
35uv run pytest --tb=short -q
36```
37
38**If a Makefile is present:**
39```powershell
40make test
41```
42
43Analyze the output for:
44- Total number of **failures** vs. **errors** (they have different root causes).
45- Common error patterns (repeated tracebacks, shared import lines).
46- Affected modules, files, and specific test cases.
47- Environment-related failures (missing env vars, missing config files, port conflicts).
48- Skipped (`SKIPPED`) or expected-fail (`XFAIL`) tests — investigate why before ignoring.
49
50Capture the list of failing test node IDs for targeted re-runs:
51```powershell
52uv run pytest --tb=line -q 2>&1 | Select-String "FAILED"
53```
54
55### 2. Smart Error Grouping
56
57Group failures to solve root causes once rather than fixing symptoms one by one.
58
59**Group by:**
60- **Error Type**: `ImportError`, `ModuleNotFoundError`, `AttributeError`, `TypeError`, `AssertionError`, `TimeoutError`.
61- **Location**: Failures concentrated in a specific module, directory, or test file.
62- **Root Cause**: API breaking changes, dependency updates, configuration drift, fixture issues, environment mismatches.
63
64**Prioritize groups by:**
651. **Impact** — Fix the error causing the most failures first.
662. **Dependency Order** — Fix infrastructure/setup failures before business logic failures. A single `ImportError` can cascade into dozens of downstream failures.
67
68### 3. Fix Order Strategy
69
70Follow this hierarchy to ensure a stable foundation before addressing higher-level logic:
71
72**Level 1 — Infrastructure & Environment**
73- `ImportError`, `ModuleNotFoundError`
74- Missing dependencies or incorrect `pyproject.toml` / `requirements.txt`
75- Environment variable or configuration mismatches
76- Fixture setup/teardown failures
77- Database or service connection errors
78
79**Level 2 — Interface & API Changes**
80- Function signature mismatches (`TypeError`)
81- Renamed methods or moved modules (`AttributeError`)
82- Updated return types or data structures (e.g., `dict` → dataclass)
83- Changed CLI flags or API response shapes
84
85**Level 3 — Logic & Behavioral Issues**
86- `AssertionError` (incorrect values)
87- Edge case failures (empty input, boundary values, timezone issues)
88- Race conditions or timeout issues
89- Flaky tests (intermittent failures)
90
91### 4. Systematic Fixing Process (Per Group)
92
93For each group, starting with the highest priority:
94
95#### 4a. Identify Root Cause
96- Read the traceback from the **bottom up** — the last frame usually points to the failing line.
97- Correlate failures with recent changes:
98 ```powershell
99 git diff HEAD~5 --name-only
100 git log --oneline -10
101 ```
102- Inspect the failing line of code and the corresponding test assertion side by side.
103- If the project has a `references/` directory with architecture or API docs, load the relevant reference file to understand expected behavior before editing.
104
105#### 4b. Implement Fix
106- Apply targeted, minimal changes using the Edit tool.
107- Adhere to project-specific coding standards (refer to `CLAUDE.md` or equivalent).
108- Keep changes minimal to avoid introducing new regressions.
109- If a `scripts/` directory contains helper scripts (e.g., lint, format, type-check), run them after each fix to catch side effects early.
110
111#### 4c. Verify Fix (Iterative Validation)
112Run only the affected subset of tests to save time and reduce noise.
113
114```powershell
115# Run a specific test file
116uv run pytest tests/path/to/test_file.py -v
117
118# Run tests matching a specific keyword/pattern
119uv run pytest -k "keyword" -v
120
121# Run only failing tests from the last run
122uv run pytest --lf -v
123
124# Run a single test node ID
125uv run pytest tests/path/to/test_file.py::TestClass::test_method -v
126
127# Extra verbose output for deep debugging
128uv run pytest tests/path/to/test_file.py -vv --tb=long
129```
130
131Ensure the current group passes **completely** before moving to the next group.
132
133#### 4d. Move to Next Group
134Repeat 4a–4c for the next priority group.
135
136### 5. Final Verification
137
138Once all groups are addressed:
139
140```powershell
141# Run the complete test suite
142uv run pytest --tb=short
143
144# Or via Makefile
145make test
146```
147
148- Verify that **no new regressions** were introduced in previously passing modules.
149- Check coverage reports if available to ensure no critical paths were accidentally skipped:
150 ```powershell
151 uv run pytest --cov=src --cov-report=term-missing
152 ```
153- Remove all temporary debug prints/logs added during investigation.
154- Run linters and formatters if configured:
155 ```powershell
156 uv run ruff check . --fix
157 uv run ruff format .
158 ```
159
160## Pitfalls
161
162- **Do not** ignore `SKIPPED` or `XFAIL` tests without investigating why they are skipped — they may mask real failures.
163- **Do not** modify the test suite to match incorrect behavior in the code. If the test is wrong, confirm the expected behavior first, then update the test with a clear reason.
164- **Do not** use `pytest.mark.skip` as a temporary fix without a corresponding `TODO` comment or ticket reference.
165- **Do not** perform bulk "find and replace" across the codebase without verifying the impact on all affected tests.
166- **Do not** comment out failing tests or weaken assertions just to make the suite pass.
167- **Do not** fix symptoms individually ("whack-a-mole") — always group and address root causes.
168- **Do not** run the full suite after every single change — use targeted subset runs to maintain a fast feedback loop.
169- **Do not** forget to remove debug `print()` statements or temporary logging added during investigation.
170- **Do not** commit fixes for multiple unrelated groups in a single atomic commit if the project expects granular history — prefer one commit per root-cause group.
171- **Watch for flaky tests**: if a test passes on re-run but failed initially, investigate race conditions, time-dependent logic, or shared mutable state before dismissing it.
172- **Watch for environment drift**: failures that only appear in CI but not locally often indicate missing env vars, different Python/Node versions, or OS-specific path handling (especially Windows vs. Linux path separators).
173
174## Verification
175
176Confirm each item before declaring the task complete:
177
178- [ ] All tests in each failing group pass individually.
179- [ ] The full test suite runs without errors:
180 ```powershell
181 uv run pytest --tb=short
182 ```
183- [ ] No new regressions introduced in previously passing modules.
184- [ ] Code adheres to the project's style guide and architecture (`CLAUDE.md` / `CONTRIBUTING.md`).
185- [ ] All temporary debug prints/logs have been removed.
186- [ ] Linters and formatters pass (if configured).
187- [ ] `SKIPPED` and `XFAIL` tests have been investigated and documented if still skipped.
188- [ ] Coverage has not dropped on critical paths (if coverage is tracked).
189
190## Examples
191
192**Scenario**: User reports "The tests are failing after my refactor."
193
1941. **Run**: `uv run pytest --tb=short -q` → 15 failures.
1952. **Group**:
196 - 8 × `ImportError` → Root: `utils.py` moved to `core/utils.py`.
197 - 5 × `AttributeError` → Root: `get_user()` now returns a `User` object instead of a `dict`.
198 - 2 × `AssertionError` → Root: Logic bug in date calculation.
1993. **Fix Group 1** (Infrastructure): Update imports across affected files → Run `uv run pytest tests/test_utils.py -v` → Pass.
2004. **Fix Group 2** (Interface): Update call sites to access object attributes (`user.name` instead of `user["name"]`) → Run `uv run pytest tests/test_users.py -v` → Pass.
2015. **Fix Group 3** (Logic): Correct date calculation edge case → Run `uv run pytest tests/test_dates.py -v` → Pass.
2026. **Final**: Run `uv run pytest --tb=short` → All pass ✓.
203
204## Related Skills
205
206- `debugging` — General debugging workflows for non-test-specific failures.
207- `code-review` — Reviewing fixes before commit to ensure minimal, standards-compliant changes.
208- `refactoring` — Safe refactoring practices that minimize test breakage.