协作头脑风暴
brainstorming
在实现前澄清需求、探索设计选择,并形成清晰的开发方向。
regression-root-cause-analyzer【开发与工程】Locate root causes of failing regression tests by analyzing code changes, error messages, and test dependencies. Use when regression tests start failing after code changes, investigating test failures in CI/CD, debugging flaky tests, or understanding why previously passing tests now fail. Analyzes git diffs, stack traces, test output, and dependency …
独立 GitHub 快照 · 自动分类 · 以原作者文档为准
Systematically investigate failing regression tests to identify root causes by analyzing code changes, error messages, test dependencies, and common failure patterns.
Collect essential details about the test failure:
Test failure details:
Quick commands to gather info:
# Run the failing test
pytest path/to/test_file.py::test_name -v
# Get recent commits
git log --oneline -10
# Check current branch and status
git status
git branch
# See what changed recently
git log --since="1 week ago" --oneline
# Check for uncommitted changes
git diff
Parse the error message and stack trace for clues. See failure-patterns.md for common patterns.
Error type indicators:
ImportError / ModuleNotFoundError:
ImportError: cannot import name 'UserService' from 'app.services'
app/services/AttributeError:
AttributeError: 'User' object has no attribute 'email_address'
User class definition changesTypeError (arguments):
TypeError: process_data() got an unexpected keyword argument 'format'
process_data definition and recent changesAssertionError:
AssertionError: assert 3 == 2
KeyError / IndexError:
KeyError: 'status'
Use git to find what changed since tests last passed.
# If you know the last good commit
git diff <last-good-commit> <current-commit>
# Check specific file changes
git log -p path/to/file.py
# See what changed in last N commits
git log -p -n 5
# Find commits that touched specific function
git log -S "function_name" -p
Priority order for investigation:
Commands to find changes:
# What files changed recently?
git diff --name-only HEAD~5..HEAD
# Changes to specific file
git diff HEAD~5..HEAD path/to/file.py
# Changes to test file
git diff HEAD~5..HEAD path/to/test_file.py
# Changes to requirements
git diff HEAD~5..HEAD requirements.txt package.json
Match the error to common patterns:
Symptoms:
TypeError: missing required argumentTypeError: got unexpected keyword argumentInvestigation steps:
grep -r "def function_name" .git log -p -S "def function_name"Symptoms:
AttributeError when accessing return valueTypeError: 'NoneType' object is not iterableInvestigation steps:
return [] to return NoneSymptoms:
pip install or npm installInvestigation steps:
git diff HEAD~5..HEAD requirements.txtSymptoms:
Investigation steps:
pytest test_file.py::test_oneProduce a structured markdown report:
test_user_registrationTypeError: process_user() got an unexpected keyword argument 'email_format'The process_user() function signature changed in commit abc123. The parameter email_format was renamed to email_type.
Evidence:
app/users.pydef process_user(data, email_format="html")def process_user(data, email_type="html")process_user(user_data, email_format="html")This is the direct cause of the TypeError.
Update test to use new parameter name:
# Before
result = process_user(user_data, email_format="html")
# After
result = process_user(user_data, email_type="html")
The function behavior is otherwise unchanged. Only the parameter name differs.
Likelihood: Low (10%)
The test fixture might have changed, but review shows fixtures are unchanged.
Likelihood: Very Low (5%)
Could be environment-related, but error is consistent locally and in CI.
pytest tests/test_users.py::test_user_registrationpytest tests/test_users.py::test_user_registrationBefore finalizing the analysis:
Test the hypothesis:
If fix doesn't work:
Commands to verify:
# Run the specific failing test
pytest path/to/test.py::test_name -v
# Run all related tests
pytest path/to/test.py -v
# Run with verbose output
pytest path/to/test.py::test_name -vv
# Run with print statements visible
pytest path/to/test.py::test_name -s
Find exact commit that broke tests:
# Start bisect
git bisect start
# Mark current (broken) commit
git bisect bad
# Mark last known good commit
git bisect good <commit-hash>
# Git will checkout middle commit
# Run tests, then mark good or bad
pytest tests/
# If tests pass
git bisect good
# If tests fail
git bisect bad
# Repeat until git finds the breaking commit
Diff approach:
# Compare file between commits
git diff <good-commit>:<path> <bad-commit>:<path>
# Show file at specific commit
git show <commit>:path/to/file.py
Checkout approach:
# Temporarily checkout old version
git checkout <good-commit> path/to/file.py
# Run tests
pytest tests/
# Restore current version
git checkout HEAD path/to/file.py
Minimal reproduction:
Example:
# Simplified test
def test_minimal_repro():
# Reproduce just the failing assertion
result = function_under_test(input)
assert result == expected # This fails
Fixture issues:
# Check what fixtures provide
def test_debug_fixture(sample_user):
print(f"Fixture data: {sample_user}")
assert False # Force test to show output
Mock issues:
# Verify mock is called
@patch('module.function')
def test_with_mock(mock_func):
mock_func.return_value = "test"
result = code_that_uses_function()
print(f"Mock called: {mock_func.called}")
print(f"Call args: {mock_func.call_args}")
Setup/teardown:
# Check state before/after
def test_check_state():
print(f"Before: {get_current_state()}")
run_test_code()
print(f"After: {get_current_state()}")
# Show commits that changed a file
git log --follow path/to/file.py
# Show commits with specific content
git log -S "function_name" --source --all
# Show commits by author
git log --author="AuthorName" --since="1 week ago"
# Show detailed commit
git show <commit-hash>
# Compare branches
git diff main feature-branch
# Run with maximum verbosity
pytest -vv
# Show print statements
pytest -s
# Stop at first failure
pytest -x
# Show local variables on failure
pytest -l
# Run last failed tests
pytest --lf
# Run tests that failed, then all
pytest --ff
# Collect tests without running
pytest --collect-only
# Show slowest tests
pytest --durations=10
# Add breakpoint
import pdb; pdb.set_trace()
# Or in Python 3.7+
breakpoint()
# Print stack trace
import traceback
traceback.print_stack()
# Inspect object
import pprint
pprint.pprint(vars(obj))
User request:
"Tests started failing with TypeError about unexpected keyword argument"
Investigation:
TypeError: process() got unexpected keyword argument 'format'grep -r "def process" .git log -p -S "def process"Report:
## Root Cause: Parameter Renamed
Function `process()` parameter `format` renamed to `output_format` in commit abc123.
**Fix**: Update test call from `process(data, format="json")` to `process(data, output_format="json")`
**Likelihood**: High (99%)
User request:
"Test passes sometimes but fails randomly"
Investigation:
for i in {1..10}; do pytest test.py; doneReport:
## Root Cause: Race Condition
Test has race condition in async code. The async operation sometimes completes before assertion, sometimes after.
**Evidence**: Test fails ~30% of the time when run repeatedly.
**Fix**: Add proper await or increase timeout.
**Likelihood**: High (85%)
User request:
"All tests started failing after pip install"
Investigation:
git diff HEAD~1 requirements.txtrequests 2.28.0 → 2.31.0pip install requests==2.28.0Report:
## Root Cause: Breaking Change in requests 2.31.0
The `requests` library changed response encoding behavior in v2.31.0.
**Evidence**:
- Tests pass with requests==2.28.0
- Tests fail with requests==2.31.0
- Changelog mentions encoding changes
**Fix**: Update test expectations or pin requests version.
**Likelihood**: High (95%)
Start with the obvious:
Follow the stack trace:
Look for patterns:
Use version control:
git bisect for complex casesVerify assumptions:
Document findings:
For comprehensive failure patterns and their causes, see failure-patterns.md.