Spaces:
Runtime error
Runtime error
File size: 4,336 Bytes
35b8d61 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 |
#!/usr/bin/env python
"""Generate a markdown summary of the test suite."""
import ast
import os
from pathlib import Path
def summarize_tests(start_dir: str, output_file: str):
"""
Parses Python test files to extract test function names and their docstrings,
then writes a summary to a markdown file.
"""
project_root = Path(__file__).parent.parent
search_path = project_root / start_dir
output_path = project_root / output_file
# First pass: collect counts by category
counts = {
"unit": {"files": 0, "tests": 0},
"integration": {"files": 0, "tests": 0},
"other": {"files": 0, "tests": 0},
}
for root, _, files in os.walk(search_path):
for file in files:
if file.startswith("test_") and file.endswith(".py"):
file_path = Path(root) / file
relative_path = str(file_path.relative_to(project_root))
# Determine category based on markers or path
if "/unit/" in relative_path or "_unit" in file:
category = "unit"
elif "/integration/" in relative_path or "integration" in file:
category = "integration"
else:
category = "other"
counts[category]["files"] += 1
try:
with open(file_path, "r", encoding="utf-8") as f:
source = f.read()
tree = ast.parse(source)
for node in ast.walk(tree):
# Count both sync and async test functions
if isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef)) and node.name.startswith("test_"):
counts[category]["tests"] += 1
except Exception:
pass
# Build summary with counts header
total_files = sum(c["files"] for c in counts.values())
total_tests = sum(c["tests"] for c in counts.values())
summary_lines = [
"# Test Suite Summary\n",
"## Overview\n",
"| Category | Files | Tests |",
"|----------|-------|-------|",
f"| Unit | {counts['unit']['files']} | {counts['unit']['tests']} |",
f"| Integration | {counts['integration']['files']} | {counts['integration']['tests']} |",
]
if counts["other"]["files"] > 0:
summary_lines.append(f"| Other | {counts['other']['files']} | {counts['other']['tests']} |")
summary_lines.extend([
f"| **Total** | **{total_files}** | **{total_tests}** |",
"",
])
# Second pass: detailed listing
for root, _, files in os.walk(search_path):
for file in sorted(files):
if file.startswith("test_") and file.endswith(".py"):
file_path = Path(root) / file
relative_path = file_path.relative_to(project_root)
summary_lines.append(f"\n## `{relative_path}`\n")
try:
with open(file_path, "r", encoding="utf-8") as f:
source = f.read()
tree = ast.parse(source)
for node in ast.walk(tree):
# Include both sync and async test functions
if isinstance(node, (ast.FunctionDef, ast.AsyncFunctionDef)) and node.name.startswith("test_"):
docstring = ast.get_docstring(node)
summary_lines.append(f"- **`{node.name}`**")
if docstring:
# Clean up the docstring for single-line display
first_line = docstring.strip().split("\n")[0]
summary_lines.append(f" - *{first_line}*")
except Exception as e:
summary_lines.append(f"- Error parsing file: {e}")
with open(output_path, "w", encoding="utf-8") as f:
f.write("\n".join(summary_lines))
print(f"Test suite summary generated at: {output_path}")
if __name__ == "__main__":
# Configuration for prompt-prix
TEST_DIRECTORY = "tests"
OUTPUT_MARKDOWN_FILE = "docs/TEST_SUMMARY.md"
summarize_tests(TEST_DIRECTORY, OUTPUT_MARKDOWN_FILE)
|