Analyze test code structure directly to provide coverage analysis
This skill inherits all available tools. When active, it can use any tool Claude has access to.
README.mdThis skill provides the ability to analyze test code structure directly from test files without running tests. It examines test files and source files to identify what is tested and what is not.
Use this skill when you need to:
# Ensure Python 3.8+ is installed
python3 --version
# Go toolchain for target project
go version
Note: This skill currently supports Go projects only.
The analyzer discovers test and source files based on Go conventions:
Test Files:
_test.go*e2e*_test.go, *integration*_test.gotest/e2e/, test/integration/, e2e/, integration/[Serial], [Disruptive], g.Describe(, g.It(Source Files:
.go (excluding test files)For each test file, extract:
Test functions/methods:
Test targets (what the test is testing):
Test metadata:
Example for Go:
// File: pkg/handler_test.go
package handler_test
import (
"testing"
"myapp/pkg/handler"
)
func TestHandleRequest(t *testing.T) { // ← Test function
h := handler.New() // ← Target: handler.New
result := h.HandleRequest("test") // ← Target: handler.HandleRequest
// ...
}
Extraction result:
{
"test_file": "pkg/handler_test.go",
"source_file": "pkg/handler.go",
"tests": [
{
"name": "TestHandleRequest",
"lines": [6, 10],
"targets": ["handler.New", "handler.HandleRequest"],
"type": "unit"
}
]
}
For each source file, extract:
Functions/methods:
Classes/structs:
Example for Go:
// File: pkg/handler.go
package handler
type Handler struct {
config Config
}
func New() *Handler { // ← Function: New
return &Handler{}
}
func (h *Handler) HandleRequest(req string) (string, error) { // ← Function: HandleRequest
if req == "" {
return "", errors.New("empty request")
}
return process(req), nil
}
Extraction result:
{
"source_file": "pkg/handler.go",
"functions": [
{
"name": "New",
"lines": [8, 10],
"visibility": "exported",
"complexity": 1
},
{
"name": "HandleRequest",
"lines": [12, 20],
"visibility": "exported",
"complexity": 3,
"receiver": "Handler"
}
]
}
Create a mapping between tests and source code:
Direct mapping (test file → source file):
handler_test.go → handler.goFunction-level mapping (test → function):
TestHandleRequest tests HandleRequestImport-based mapping:
Mapping result:
{
"pkg/handler.go": {
"test_file": "pkg/handler_test.go",
"functions": {
"New": {
"tested": true,
"tests": ["TestHandleRequest"],
"test_count": 1
},
"HandleRequest": {
"tested": true,
"tests": ["TestHandleRequest"],
"test_count": 1
}
},
"overall_tested_functions": 2,
"overall_untested_functions": 0,
"function_test_coverage": 100.0
}
}
Identify what is not tested:
Untested source files:
Untested functions:
Partially tested files:
Gap categorization:
{
"gaps": {
"untested_files": [
{
"file": "pkg/config.go",
"functions": 5,
"exported_functions": 3,
"priority": "high",
"reason": "No corresponding test file found"
}
],
"untested_functions": [
{
"file": "pkg/handler.go",
"function": "process",
"visibility": "private",
"priority": "low",
"reason": "Not referenced in any tests"
}
]
},
"summary": {
"total_source_files": 45,
"files_with_tests": 30,
"files_without_tests": 15,
"total_functions": 234,
"tested_functions": 189,
"untested_functions": 45,
"function_coverage_percentage": 80.8
}
}
IMPORTANT: Claude Code generates all three report formats at runtime based on the analyzer's structured output. The analyzer script returns structured data (as JSON to stdout or via Python data structures), and Claude Code is responsible for generating all report files.
The analyzer generates structured data containing full analysis results. Claude Code reads this data and generates three report formats:
test-structure-report.json)Generated by: Claude Code at runtime based on analyzer output
Machine-readable format containing full analysis data. See Step 5 for structure.
How to generate:
indent=2 for readabilitytest-structure-summary.txt)Generated by: Claude Code at runtime based on analyzer output
Terminal-friendly summary showing:
Format Structure:
============================================================
Test Structure Analysis
============================================================
File: {filename}
Language: {language}
Analysis Date: {timestamp}
============================================================
Coverage Summary
============================================================
Total Source Files: {count}
Files With Tests: {count} ({percentage}%)
Files Without Tests: {count} ({percentage}%)
Total Functions: {count}
Tested Functions: {count} ({percentage}%)
Untested Functions: {count} ({percentage}%)
============================================================
High Priority Gaps
============================================================
UNTESTED FILES:
1. {filepath} - {reason} ({function_count} functions, {exported_count} exported)
...
UNTESTED FUNCTIONS:
1. {filepath}::{function} - {reason} (visibility: {visibility})
...
============================================================
Recommendations
============================================================
Current Coverage: {current}%
Target Coverage: {target}%
Focus on addressing HIGH priority gaps first to maximize
test coverage and ensure production readiness.
test-structure-report.html)Generated by: Claude Code at runtime based on analyzer output
Interactive HTML report with:
Required Sections:
Styling:
html.escape()When implementing this skill in a command:
CRITICAL: Before running any analysis, generate the analyzer script from the reference implementation.
# Create output directory
mkdir -p .work/test-coverage/analyze/
# Generate the analyzer script from the specification below
# Claude Code will write test_structure_analyzer.py based on the Analyzer Specification section
Analyzer Specification:
Generate a Python script (test_structure_analyzer.py) that analyzes Go test structure without running tests:
Input: Path or URL to a Go test file or directory Output: Structured JSON data printed to stdout, plus optional text summary to stderr
Core Algorithm:
Input Processing (handle URLs and local paths):
http:// or https://urllib.request.urlopen() to fetch content, save to temp fileFile Discovery:
*_test.go (exclude vendor, generated code)test/e2e/, test/integration/, or containing [Serial], [Disruptive] markers*.go (exclude *_test.go, vendor)Test Parsing (regex-based):
(?:g\.|o\.)?It\(\s*["']([^"']+)["'] → extract test name, line numberfunc (Test\w+)\(t \*testing\.T\) → extract test function name\w+\([^)]*\) inside test bodySource File Analysis:
func (\w+)\( or func \(\w+ \*?\w+\) (\w+)\(Test-to-Source Mapping:
handler_test.go → handler.goTestHandleRequest → HandleRequest)import statements in test filesSingle File Mode (when input is a file, not directory):
Output Format (JSON to stdout):
{
"language": "go",
"source_dir": "/path/to/src",
"test_only_mode": false,
"summary": {
"total_source_files": 45,
"total_test_files": 32,
"untested_files_count": 8
},
"test_file_details": {
"path": "/path/to/test.go",
"test_count": 15,
"tests": [
{"name": "TestFoo", "line_start": 10, "line_end": 20, "targets": ["Foo", "Bar"]}
],
"imports": ["testing", "github.com/onsi/ginkgo"]
}
}
Command-line Interface:
python3 .work/test-coverage/analyze/test_structure_analyzer.py <source-path> [--test-structure-only] [--output <dir>]
Why Runtime Generation:
.py file to maintainCheck that source directory exists and detect language if not specified.
# Run analyzer (outputs structured JSON to stdout)
python3 .work/test-coverage/analyze/test_structure_analyzer.py \
<source-directory> \
--priority <priority> \
--output-json
The analyzer will output structured JSON to stdout containing:
IMPORTANT: Claude Code generates all three report formats based on the analyzer's structured output.
import json
import subprocess
# Run analyzer and capture JSON output
result = subprocess.run(
['python3', '.work/test-coverage/analyze/test_structure_analyzer.py', source_dir, '--output-json'],
capture_output=True,
text=True
)
# Parse structured data
analysis_data = json.loads(result.stdout)
json_path = '.work/test-coverage/analyze/test-structure-report.json'
with open(json_path, 'w') as f:
json.dump(analysis_data, f, indent=2)
Follow the text format specification in Step 6 to generate a terminal-friendly summary.
text_path = '.work/test-coverage/analyze/test-structure-summary.txt'
# Generate text content following format in Step 6
with open(text_path, 'w') as f:
f.write(text_content)
Follow the HTML specification in Step 6 to generate an interactive report.
html_path = '.work/test-coverage/analyze/test-structure-report.html'
# Generate HTML content following specification in Step 6
with open(html_path, 'w') as f:
f.write(html_content)
Show summary and report locations to user:
Test Structure Analysis Complete
Reports Generated:
✓ HTML: .work/test-coverage/analyze/test-structure-report.html
✓ JSON: .work/test-coverage/analyze/test-structure-report.json
✓ Text: .work/test-coverage/analyze/test-structure-summary.txt
CRITICAL: Before declaring this skill complete, you MUST execute ALL validation checks below. Failure to validate is considered incomplete execution.
Execute these verification steps in order. ALL must pass:
# Verify all three reports exist
test -f .work/test-coverage/analyze/test-structure-report.html && echo "✓ HTML exists" || echo "✗ HTML MISSING"
test -f .work/test-coverage/analyze/test-structure-report.json && echo "✓ JSON exists" || echo "✗ JSON MISSING"
test -f .work/test-coverage/analyze/test-structure-summary.txt && echo "✓ Text exists" || echo "✗ Text MISSING"
Required: All three files must exist. If any are missing, regenerate them.
# Verify test cases were extracted
python3 << 'EOF'
import json
try:
with open('.work/test-coverage/analyze/test-structure-report.json', 'r') as f:
data = json.load(f)
test_count = data.get('summary', {}).get('test_cases_count', 0)
if test_count > 0:
print(f"✓ Test cases extracted: {test_count}")
else:
print("✗ NO TEST CASES FOUND - verify test file contains Ginkgo tests")
exit(1)
except Exception as e:
print(f"✗ ERROR: {e}")
exit(1)
EOF
Required: Test cases must be extracted. Zero test cases indicates a parsing issue.
# Verify HTML has required sections
grep -q "<h2>Test Cases" .work/test-coverage/analyze/test-structure-report.html && \
echo "✓ Test Cases section present" || \
echo "✗ MISSING: Test Cases section"
grep -q "<h2>Coverage Summary" .work/test-coverage/analyze/test-structure-report.html && \
echo "✓ Coverage Summary section present" || \
echo "✗ MISSING: Coverage Summary section"
Required: HTML must have all structural sections.
# Verify JSON has all required fields
python3 << 'EOF'
import json
try:
with open('.work/test-coverage/analyze/test-structure-report.json', 'r') as f:
data = json.load(f)
required_fields = [
('summary.language', lambda d: d['summary']['language']),
('summary.test_cases_count', lambda d: d['summary']['test_cases_count']),
('test_cases', lambda d: d['test_cases']),
]
missing = []
for name, getter in required_fields:
try:
getter(data)
print(f"✓ {name}")
except (KeyError, TypeError):
print(f"✗ MISSING: {name}")
missing.append(name)
if not missing:
print("\n✓ All required JSON fields present")
else:
print(f"\n✗ INCOMPLETE: Missing {len(missing)} required fields")
exit(1)
except Exception as e:
print(f"✗ ERROR: {e}")
exit(1)
EOF
Required: All required JSON fields must be present.
Before declaring this skill complete:
If ANY check fails: Fix the issue and re-run all validation checks. Do NOT declare the skill complete until ALL checks pass.
Unable to parse test/source files:
No test files found:
*_test.go naming conventionComplex project structures:
--exclude# Analyze test structure for Go project
python3 .work/test-coverage/analyze/test_structure_analyzer.py /path/to/go/project
# Output:
# Language: go
# Discovered 45 source files, 32 test files
# Function coverage: 80.8% (189/234 functions tested)
# High priority gaps: 8 files without tests
# Analyze only high-priority gaps
python3 .work/test-coverage/analyze/test_structure_analyzer.py /path/to/go/project \
--priority high \
--exclude "*/vendor/*" \
--output reports/test-gaps/
# Analyze single test file structure
python3 .work/test-coverage/analyze/test_structure_analyzer.py ./test/e2e/networking/infw.go \
--test-structure-only \
--output ./reports/
This skill is used by:
/test-coverage:analyze <source-dir>The command invokes this skill to perform test structure analysis without running tests.