Test Generation and Bug Fixing
Section Goal: Enable the AI coding assistant to automatically generate unit tests, and locate and fix bugs in code.
Testing Strategy Overview
An AI coding assistant can play three levels of roles in testing:
| Level | Capability | Description |
|---|---|---|
| L1 Test Generation | Automatically generate unit tests | Analyze function signatures and logic, generate test cases |
| L2 Bug Diagnosis | Analyze errors and locate root causes | Understand error messages, stack traces, code logic |
| L3 Auto-Fix | Generate fix code and verify | Fix → run tests → confirm passing closed loop |
Automatic Test Generation
class TestGenerator:
"""Automatic test generator"""
def __init__(self, llm):
self.llm = llm
async def generate_tests(
self,
source_code: str,
file_path: str,
framework: str = "pytest"
) -> str:
"""Automatically generate tests for given code"""
prompt = f"""Please generate comprehensive unit tests for the following code.
Source code file: {file_path}
```python
{source_code}
Test framework: {framework}
Requirements:
- Generate at least 2 test cases for each public function/method
- Cover normal cases, edge cases, and exception cases
- Test names should clearly express the test intent
- Use {framework} best practices
Please generate the complete test file code. """ response = await self.llm.ainvoke(prompt) return response.content
async def analyze_coverage(
self,
source_code: str,
test_code: str,
) -> dict:
"""Analyze test coverage and suggest what tests to add"""
prompt = f"""Analyze the coverage of the following test code against the source code.
Source code:
{source_code}
Existing tests:
{test_code}
Please analyze:
- Which functions/branches are already covered by tests
- Which functions/branches are not yet covered
- Suggested additional test cases
Return in JSON format: {{ "covered": ["List of covered functions/branches"], "uncovered": ["List of uncovered functions/branches"], "suggestions": ["Descriptions of suggested test cases"] }} """ response = await self.llm.ainvoke(prompt) import json return json.loads(response.content)
---
## Bug Localization and Fixing
```python
class BugFixer:
"""Bug localization and fixing"""
def __init__(self, llm):
self.llm = llm
async def diagnose_and_fix(
self,
code: str,
error_message: str,
file_path: str
) -> dict:
"""Diagnose and fix a bug"""
prompt = f"""The following code encountered an error at runtime. Please help diagnose and fix it.
File: {file_path}
Code:
```python
{code}
Error message:
{error_message}
Please analyze:
- The root cause of the error
- The location of the problematic code
- The fix solution
Reply in JSON format: {{ "root_cause": "Root cause analysis", "bug_location": "Problematic function/line number", "fix_description": "Fix solution description", "fixed_code": "Complete fixed code" }} """
response = await self.llm.ainvoke(prompt)
import json
return json.loads(response.content)
async def suggest_preventive_measures(
self,
bug_info: dict
) -> list[str]:
"""Based on bug analysis, suggest preventive measures"""
prompt = f"""Based on the following bug analysis, provide 3–5 suggestions to prevent similar issues from recurring:
Root cause: {bug_info['root_cause']} Location: {bug_info['bug_location']} Fix: {bug_info['fix_description']}
Please return a list of suggestions (one per line). """ response = await self.llm.ainvoke(prompt) return response.content.strip().split('\n')
---
## Integrated Use: Test-Diagnose-Fix Closed Loop
```python
async def fix_workflow(llm, code: str, test_code: str):
"""Fix workflow: run tests → find failures → auto-fix → verify fix"""
fixer = BugFixer(llm)
test_gen = TestGenerator(llm)
# 1. If no tests exist, generate them first
if not test_code:
test_code = await test_gen.generate_tests(code, "main.py")
print("✅ Test cases generated")
# 2. Run tests (simplified demo)
print("🧪 Running tests...")
# result = subprocess.run(["python", "-m", "pytest", ...])
# 3. If there are failing tests, let the Agent fix them
error_msg = "AssertionError: expected 42, got 0"
fix_result = await fixer.diagnose_and_fix(
code=code,
error_message=error_msg,
file_path="main.py"
)
print(f"🔍 Cause: {fix_result['root_cause']}")
print(f"🔧 Fix: {fix_result['fix_description']}")
print(f"📝 Location: {fix_result['bug_location']}")
# 4. Verify fix (regression testing)
print("🔄 Regression test: verifying fix doesn't introduce new issues...")
# re-run tests with fixed code
# 5. Preventive suggestions
preventive = await fixer.suggest_preventive_measures(fix_result)
print("💡 Preventive suggestions:")
for suggestion in preventive:
print(f" {suggestion}")
return fix_result["fixed_code"]
Best Practices
When integrating AI-generated tests and fixes into the development workflow:
best_practices = {
"Human review": "AI-generated tests and fix suggestions must be reviewed by humans before merging",
"Incremental testing": "Generate tests for new/modified code first, gradually cover existing code",
"Test quality": "Check if AI-generated tests truly validate business logic, not just 'padding coverage'",
"Fix verification": "After auto-fix, run the full test suite (regression tests) to prevent fixes from introducing new issues",
"Record and learn": "Record common bug patterns in the knowledge base to help the Agent improve diagnostic accuracy",
}
Summary
| Feature | Description |
|---|---|
| Test generation | Automatically generate pytest test cases for code |
| Bug diagnosis | Analyze error messages, locate root causes |
| Auto-fix | Generate fixed code |
| Fix workflow | Closed loop of test → diagnose → fix |
Next Section Preview: Finally, we'll integrate all components into a complete AI coding assistant.