第六章:测试与调试¶
测试策略¶
测试层次¶
┌─────────────────────────────────────────────────────────────┐
│ │
│ 第一层:结构验证 │
│ ┌─────────────────────────────────────────────────────────┐│
│ │ - SKILL.md 是否存在 ││
│ │ - frontmatter 格式是否正确 ││
│ │ - 目录结构是否合规 ││
│ └─────────────────────────────────────────────────────────┘│
│ │
│ 第二层:内容验证 │
│ ┌─────────────────────────────────────────────────────────┐│
│ │ - description 是否完整 ││
│ │ - 引用文件是否存在 ││
│ │ - 脚本是否可执行 ││
│ └─────────────────────────────────────────────────────────┘│
│ │
│ 第三层:功能测试 │
│ ┌─────────────────────────────────────────────────────────┐│
│ │ - 脚本执行是否正确 ││
│ │ - 输出是否符合预期 ││
│ │ - 错误处理是否完善 ││
│ └─────────────────────────────────────────────────────────┘│
│ │
│ 第四层:集成测试 │
│ ┌─────────────────────────────────────────────────────────┐│
│ │ - Agent 是否能正确触发 ││
│ │ - 工作流是否完整执行 ││
│ │ - 输出是否满足需求 ││
│ └─────────────────────────────────────────────────────────┘│
│ │
└─────────────────────────────────────────────────────────────┘
结构验证¶
使用验证脚本¶
# 验证 Skill 结构
python scripts/validate_skill.py path/to/skill
# 输出示例
✓ SKILL.md 存在
✓ YAML frontmatter 格式正确
✓ name 字段存在
✓ description 字段存在
✓ 目录名与 name 一致
✓ 无禁止文件(README.md 等)
✓ 无符号链接
手动验证清单¶
validation-checklist:
required-files:
- [ ] SKILL.md 存在
frontmatter:
- [ ] 以 --- 开始和结束
- [ ] 是有效的 YAML
- [ ] 包含 name 字段
- [ ] 包含 description 字段
- [ ] 无多余字段
naming:
- [ ] name 使用小写字母
- [ ] name 只包含字母、数字、连字符
- [ ] name 长度 < 64 字符
- [ ] 目录名与 name 一致
forbidden:
- [ ] 无 README.md
- [ ] 无 CHANGELOG.md
- [ ] 无 tests/ 目录
- [ ] 无符号链接
内容验证¶
描述质量检查¶
# 检查 description 质量
def validate_description(description: str) -> list[str]:
issues = []
# 长度检查
if len(description) < 20:
issues.append("描述太短,应 > 20 字符")
# 触发条件检查
trigger_words = ['当', '使用', '需要', '支持']
if not any(word in description for word in trigger_words):
issues.append("描述缺少触发条件说明")
# 功能说明检查
if not any(c.isdigit() for c in description):
# 没有数字列表,可能缺少功能枚举
pass # 可选
return issues
引用文件检查¶
# 检查 SKILL.md 中的引用是否存在
python scripts/check_references.py path/to/skill
# 输出示例
检查 SKILL.md 中的引用...
✓ references/api-docs.md 存在
✓ references/schema.md 存在
✗ references/missing.md 不存在
✓ scripts/process.py 存在
✓ assets/template.html 存在
脚本语法检查¶
功能测试¶
脚本单元测试¶
# test_rotate_pdf.py
import pytest
from pathlib import Path
import tempfile
from scripts.rotate_pdf import rotate
class TestRotatePDF:
def test_rotate_90_degrees(self):
"""测试 90 度旋转"""
with tempfile.TemporaryDirectory() as tmpdir:
input_path = Path("tests/fixtures/sample.pdf")
output_path = Path(tmpdir) / "output.pdf"
rotate(input_path, output_path, 90)
assert output_path.exists()
# 验证旋转结果
# ...
def test_invalid_input(self):
"""测试无效输入"""
with pytest.raises(FileNotFoundError):
rotate("nonexistent.pdf", "output.pdf", 90)
def test_invalid_degrees(self):
"""测试无效角度"""
with pytest.raises(ValueError):
rotate("input.pdf", "output.pdf", 45) # 只支持 90/180/270
运行测试¶
手动测试脚本¶
# 测试脚本执行
python scripts/rotate_pdf.py \
--input tests/fixtures/sample.pdf \
--output /tmp/test_output.pdf \
--degrees 90
# 验证输出
ls -la /tmp/test_output.pdf
file /tmp/test_output.pdf
集成测试¶
测试触发¶
# 测试 Skill 是否被正确触发
## 测试用例
1. 直接匹配
用户: "帮我编辑这个 PDF"
预期: 触发 pdf-editor skill
2. 隐式匹配
用户: "这个文档需要加水印"
预期: 触发 pdf-editor skill
3. 多 Skill 场景
用户: "把这个 PDF 转成 Word 然后编辑"
预期: 可能触发多个 skill
测试工作流¶
# 集成测试示例
def test_pdf_workflow():
"""测试完整的 PDF 处理工作流"""
# 1. 准备输入
input_file = "tests/fixtures/input.pdf"
# 2. 执行工作流
# Step 1: 提取文本
text = extract_text(input_file)
assert len(text) > 0
# Step 2: 处理文本
processed = process_text(text)
# Step 3: 生成输出
output_file = "/tmp/output.pdf"
create_pdf(processed, output_file)
# 4. 验证输出
assert Path(output_file).exists()
调试技巧¶
日志记录¶
# 在脚本中添加日志
import logging
logging.basicConfig(
level=logging.DEBUG,
format='%(asctime)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)
def process(input_file):
logger.debug(f"处理文件: {input_file}")
# ...
logger.info("处理完成")
错误追踪¶
# 详细的错误信息
try:
result = process(data)
except Exception as e:
logger.error(f"处理失败: {e}")
logger.debug(f"输入数据: {data}")
logger.debug(f"堆栈追踪:", exc_info=True)
raise
交互式调试¶
# 使用 Python 调试器
python -m pdb scripts/process.py --input test.pdf
# 常用命令
# n - 下一行
# s - 进入函数
# c - 继续执行
# p variable - 打印变量
# q - 退出
常见问题¶
问题 1:Skill 不触发¶
# 可能原因
1. description 不够清晰
2. 触发条件描述不明确
3. 与其他 Skill 冲突
# 解决方案
1. 完善 description,添加更多触发场景
2. 使用数字列表明确功能
3. 检查是否有其他 Skill 的 description 重叠
问题 2:脚本执行失败¶
问题 3:输出不符合预期¶
测试清单¶
# 完整测试清单
## 结构测试
- [ ] SKILL.md 存在且格式正确
- [ ] frontmatter 包含必需字段
- [ ] 目录命名符合规范
- [ ] 无禁止文件
## 内容测试
- [ ] description 清晰完整
- [ ] 引用文件存在
- [ ] 脚本可执行
- [ ] 资源文件有效
## 功能测试
- [ ] 脚本单元测试通过
- [ ] 错误处理正确
- [ ] 输出符合预期
## 集成测试
- [ ] Skill 可被正确触发
- [ ] 工作流完整执行
- [ ] 与其他 Skill 无冲突
小结¶
本章介绍了测试与调试:
- 四层测试策略
- 结构和内容验证
- 功能测试方法
- 集成测试要点
- 调试技巧
- 常见问题解决
下一章将介绍打包与发布。