The Agent Skills Directory
npx skills add https://smithery.ai/skills/openshift-eng/test-structure-analysis此技能提供直接从测试文件分析测试代码结构的能力,无需运行测试。它会检查测试文件和源文件,以识别哪些内容已测试,哪些未测试。
在以下情况下使用此技能:
# 确保已安装 Python 3.8+
python3 --version
# 目标项目的 Go 工具链
go version
注意:此技能目前仅支持 Go 项目。
分析器根据 Go 约定发现测试文件和源文件:
测试文件:
_test.go 结尾的文件*e2e*_test.go, *integration*_test.gotest/e2e/, test/integration/, e2e/, integration/[Serial], [Disruptive], g.Describe(, g.It(源文件:
.go 结尾的文件(不包括测试文件)对于每个测试文件,提取:
Go 示例:
// File: pkg/handler_test.go
package handler_test
import (
"testing"
"myapp/pkg/handler"
)
func TestHandleRequest(t *testing.T) { // ← 测试函数
h := handler.New() // ← 目标:handler.New
result := h.HandleRequest("test") // ← 目标:handler.HandleRequest
// ...
}
提取结果:
{
"test_file": "pkg/handler_test.go",
"source_file": "pkg/handler.go",
"tests": [
{
"name": "TestHandleRequest",
"lines": [6, 10],
"targets": ["handler.New", "handler.HandleRequest"],
"type": "unit"
}
]
}
对于每个源文件,提取:
Go 示例:
// File: pkg/handler.go
package handler
type Handler struct {
config Config
}
func New() *Handler { // ← 函数:New
return &Handler{}
}
func (h *Handler) HandleRequest(req string) (string, error) { // ← 函数:HandleRequest
if req == "" {
return "", errors.New("empty request")
}
return process(req), nil
}
提取结果:
{
"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"
}
]
}
创建测试与源代码之间的映射:
handler_test.go → handler.goTestHandleRequest 测试 HandleRequest映射结果:
{
"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
}
}
识别未测试的内容:
缺口分类:
{
"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
}
}
重要提示: Claude Code 在运行时根据分析器的结构化输出生成所有三种报告格式。分析器脚本返回结构化数据(作为 JSON 输出到 stdout 或通过 Python 数据结构),Claude Code 负责生成所有报告文件。
分析器生成包含完整分析结果的结构化数据。Claude Code 读取此数据并生成三种报告格式:
test-structure-report.json)生成者: Claude Code 在运行时基于分析器输出
包含完整分析数据的机器可读格式。结构见步骤 5。
如何生成:
indent=2 以提高可读性test-structure-summary.txt)生成者: Claude Code 在运行时基于分析器输出
终端友好的摘要,显示:
格式结构:
============================================================
测试结构分析
============================================================
文件:{filename}
语言:{language}
分析日期:{timestamp}
============================================================
覆盖摘要
============================================================
总源文件数: {count}
有测试的文件: {count} ({percentage}%)
无测试的文件: {count} ({percentage}%)
总函数数: {count}
已测试函数: {count} ({percentage}%)
未测试函数: {count} ({percentage}%)
============================================================
高优先级缺口
============================================================
未测试的文件:
1. {filepath} - {reason} ({function_count} 个函数, {exported_count} 个导出)
...
未测试的函数:
1. {filepath}::{function} - {reason} (可见性: {visibility})
...
============================================================
建议
============================================================
当前覆盖率:{current}%
目标覆盖率:{target}%
首先关注解决高优先级缺口,以最大化
测试覆盖率并确保生产就绪性。
test-structure-report.html)生成者: Claude Code 在运行时基于分析器输出
交互式 HTML 报告,包含:
必需部分:
样式:
html.escape() 转义所有内容在命令中实施此技能时:
关键: 在运行任何分析之前,根据参考实现生成分析器脚本。
# 创建输出目录
mkdir -p .work/test-coverage/analyze/
# 根据下面的规范生成分析器脚本
# Claude Code 将根据“分析器规范”部分编写 test_structure_analyzer.py
分析器规范:
生成一个 Python 脚本 (test_structure_analyzer.py),用于在不运行测试的情况下分析 Go 测试结构:
输入: Go 测试文件或目录的路径或 URL 输出: 打印到 stdout 的结构化 JSON 数据,加上可选的文本摘要到 stderr
核心算法:
http:// 或 https:// 开头urllib.request.urlopen() 获取内容,保存到临时文件*_test.go(排除 vendor、生成的代码)test/e2e/, test/integration/ 中的文件,或包含 [Serial], [Disruptive] 标记的文件*.go(排除 , vendor){
"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"]
}
}
命令行界面:
python3 .work/test-coverage/analyze/test_structure_analyzer.py <source-path> [--test-structure-only] [--output <dir>]
为什么在运行时生成:
.py 文件检查源目录是否存在,如果未指定则检测语言。
# 运行分析器(将结构化 JSON 输出到 stdout)
python3 .work/test-coverage/analyze/test_structure_analyzer.py \
<source-directory> \
--priority <priority> \
--output-json
分析器将输出结构化 JSON 到 stdout,包含:
重要提示: Claude Code 根据分析器的结构化输出生成所有三种报告格式。
import json
import subprocess
# 运行分析器并捕获 JSON 输出
result = subprocess.run(
['python3', '.work/test-coverage/analyze/test_structure_analyzer.py', source_dir, '--output-json'],
capture_output=True,
text=True
)
# 解析结构化数据
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)
遵循步骤 6 中的文本格式规范,生成终端友好的摘要。
text_path = '.work/test-coverage/analyze/test-structure-summary.txt'
# 按照步骤 6 中的格式生成文本内容
with open(text_path, 'w') as f:
f.write(text_content)
遵循步骤 6 中的 HTML 规范,生成交互式报告。
html_path = '.work/test-coverage/analyze/test-structure-report.html'
# 按照步骤 6 中的规范生成 HTML 内容
with open(html_path, 'w') as f:
f.write(html_content)
向用户显示摘要和报告位置:
测试结构分析完成
生成的报告:
✓ 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
关键: 在宣布此技能完成之前,您必须执行以下所有验证检查。未经验证即视为执行不完整。
按顺序执行这些验证步骤。所有都必须通过:
# 验证所有三个报告都存在
test -f .work/test-coverage/analyze/test-structure-report.html && echo "✓ HTML 存在" || echo "✗ HTML 缺失"
test -f .work/test-coverage/analyze/test-structure-report.json && echo "✓ JSON 存在" || echo "✗ JSON 缺失"
test -f .work/test-coverage/analyze/test-structure-summary.txt && echo "✓ 文本存在" || echo "✗ 文本缺失"
要求: 所有三个文件都必须存在。如果缺少任何文件,请重新生成它们。
# 验证测试用例已提取
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_count}")
else:
print("✗ 未找到测试用例 - 验证测试文件是否包含 Ginkgo 测试")
exit(1)
except Exception as e:
print(f"✗ 错误:{e}")
exit(1)
EOF
要求: 必须提取到测试用例。零个测试用例表明存在解析问题。
# 验证 HTML 包含必需部分
grep -q "<h2>Test Cases" .work/test-coverage/analyze/test-structure-report.html && \
echo "✓ 测试用例部分存在" || \
echo "✗ 缺失:测试用例部分"
grep -q "<h2>Coverage Summary" .work/test-coverage/analyze/test-structure-report.html && \
echo "✓ 覆盖摘要部分存在" || \
echo "✗ 缺失:覆盖摘要部分"
要求: HTML 必须包含所有结构部分。
# 验证 JSON 包含所有必需字段
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"✗ 缺失:{name}")
missing.append(name)
if not missing:
print("\n✓ 所有必需的 JSON 字段都存在")
else:
print(f"\n✗ 不完整:缺少 {len(missing)} 个必需字段")
exit(1)
except Exception as e:
print(f"✗ 错误:{e}")
exit(1)
EOF
要求: 所有必需的 JSON 字段都必须存在。
在宣布此技能完成之前:
如果任何检查失败: 修复问题并重新运行所有验证检查。在所有检查通过之前,请不要宣布技能完成。
*_test.go 命名约定--exclude 排除某些目录# 分析 Go 项目的测试结构
python3 .work/test-coverage/analyze/test_structure_analyzer.py /path/to/go/project
# 输出:
# 语言:go
# 发现 45 个源文件,32 个测试文件
# 函数覆盖率:80.8%(189/234 个函数已测试)
# 高优先级缺口:8 个文件没有测试
# 仅分析高优先级缺口
python3 .work/test-coverage/analyze/test_structure_analyzer.py /path/to/go/project \
--priority high \
--exclude "*/vendor/*" \
--output reports/test-gaps/
# 分析单个测试文件结构
python3 .work/test-coverage/analyze/test_structure_analyzer.py ./test/e2e/networking/infw.go \
--test-structure-only \
--output ./reports/
此技能被以下命令使用:
/test-coverage:analyze <source-dir>该命令调用此技能以在不运行测试的情况下执行测试结构分析。
每周安装次数
–
来源
首次出现
–
This 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广告位招租
在这里展示您的产品或服务
触达数万 AI 开发者,精准高效
*_test.go(?:g\.|o\.)?It\(\s*["']([^"']+)["'] → 提取测试名称、行号func (Test\w+)\(t \*testing\.T\) → 提取测试函数名\w+\([^)]*\) 正则表达式func (\w+)\( 或 func \(\w+ \*?\w+\) (\w+)\(handler_test.go → handler.goTestHandleRequest → HandleRequest)import 语句*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.
Weekly Installs
–
Source
First Seen
–
测试策略完整指南:单元/集成/E2E测试金字塔与自动化实践
11,200 周安装