annator-command-center / tests /scripts /generate_gap_analysis.py
techprotrade's picture
Deploy ATOM FastAPI command center runtime (part 9)
81e3673 verified
Raw
History Blame Contribute Delete
3.66 kB
#!/usr/bin/env python3
"""
Generate gap analysis from baseline coverage report.
Analyzes coverage gaps and prioritizes files by:
1. Potential coverage gain (uncovered lines)
2. Business impact (core vs. utilities)
3. Test complexity (unit vs. integration needs)
Usage:
python3 tests/scripts/generate_gap_analysis.py
"""
import json
from pathlib import Path
from datetime import datetime, timezone
# Load baseline coverage
baseline_path = Path("tests/coverage_reports/metrics/phase_127_baseline.json")
with open(baseline_path) as f:
coverage_data = json.load(f)
# Analyze gaps
gaps = []
for file_path, file_data in coverage_data["files"].items():
# Filter out test files and non-production code
if any(x in file_path for x in ["tests/", "test_", "__pycache__", "migrations/"]):
continue
pct = file_data["summary"]["percent_covered"]
total = file_data["summary"]["num_statements"]
covered = file_data["summary"]["covered_lines"]
missing = total - covered
if pct < 80.0:
# Determine complexity by lines of code
complexity = "high" if total > 500 else "medium" if total > 200 else "low"
# Determine business impact by module
if "core/" in file_path:
impact = "high" if any(x in file_path for x in ["models", "workflow", "agent", "episode"]) else "medium"
elif "api/" in file_path:
impact = "high"
else:
impact = "low"
# Calculate priority score
priority_score = missing * (3 if impact == "high" else 2 if impact == "medium" else 1)
gaps.append({
"file": file_path.replace("backend/", ""),
"coverage_percent": round(pct, 2),
"lines_total": total,
"lines_covered": covered,
"lines_missing": missing,
"complexity": complexity,
"business_impact": impact,
"priority_score": priority_score,
"gap_to_target": round(80.0 - pct, 2)
})
# Sort by priority score (descending)
gaps.sort(key=lambda x: x["priority_score"], reverse=True)
# Calculate overall metrics
total_lines = sum(f["summary"]["num_statements"] for f in coverage_data["files"].values())
total_covered = sum(f["summary"]["covered_lines"] for f in coverage_data["files"].values())
overall_pct = (total_covered / total_lines * 100) if total_lines > 0 else 0
# Generate output
gap_analysis = {
"generated_at": datetime.now(timezone.utc).isoformat(),
"baseline_coverage": round(overall_pct, 2),
"target_coverage": 80.0,
"gap_to_target": round(80.0 - overall_pct, 2),
"files_below_target": len(gaps),
"total_missing_lines": sum(g["lines_missing"] for g in gaps),
"estimated_lines_needed": round(sum(g["lines_missing"] for g in gaps) * 0.5), # Assume 50% efficiency
"high_impact_files": [g for g in gaps if g["business_impact"] == "high"][:30],
"medium_impact_files": [g for g in gaps if g["business_impact"] == "medium"][:30],
"low_impact_files": [g for g in gaps if g["business_impact"] == "low"][:30]
}
# Write output
output_path = Path("tests/coverage_reports/metrics/phase_127_gap_analysis.json")
output_path.parent.mkdir(parents=True, exist_ok=True)
with open(output_path, "w") as f:
json.dump(gap_analysis, f, indent=2)
print(f"Gap analysis complete: {overall_pct:.2f}% → 80% target")
print(f"Files below 80%: {len(gaps)}")
print(f"Estimated lines needed: {gap_analysis['estimated_lines_needed']}")
print(f"Top 10 high-impact targets:")
for g in gaps[:10]:
print(f" {g['file']}: {g['coverage_percent']}% ({g['lines_missing']} missing lines, priority={g['priority_score']})")