关于 improving-python-coverage
供 Agent 使用的 Python 单元测试覆盖率提升技能,通过分析未覆盖代码、补充有价值的测试并反复测量和审查来提高覆盖率。
主要功能
- 01按覆盖数据确定文件优先级
- 02测试分支与边界情况
- 03迭代验证覆盖率
- 04集成测试依赖指导
- 05简化与审查工作流
适用场景
- 01为覆盖不足的 Python 模块补充测试
- 02测试错误路径和边界输入
- 03检查可选依赖的测试行为
- 04运行项目检查前提升覆盖率
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ streamlit/ streamlit --skill improving-python-coverage安装后在 Claude Code 中输入/improving-python-coverage确认已加载。
详细介绍
提升 Python 覆盖率
通过有实际价值的有效测试,将 Python 单元测试覆盖率提高约 0.2%。
完全自主执行 —— 不要停下来或暂停以请求确认。持续迭代(分析 → 实现 → 验证),直到达成 0.2% 的覆盖率目标。如果你对要测试的内容遇到不确定之处,做出合理选择并继续推进。
工作流
第 1 步:运行带覆盖率的测试
make python-tests # ~3 min, creates .coverage file
生成用于分析的 JSON 报告:
uv run coverage json -o coverage.json
该 JSON 包含按文件划分的 missing_lines 数组,显示未覆盖的行号。
第 2 步:分析并确定优先级
读取 coverage.json,找出符合以下条件的文件:
- 体积大 +
percent_covered低于平均值(高影响) lib/streamlit/elements/或lib/streamlit/runtime/中的核心模块- 纯工具函数
跳过:覆盖率 >97%、proto/*、vendor/*、static/*、测试文件。
第 3 步:实现测试(在子 Agent 中)
启动一个子 Agent,为每个优先文件实现测试。向子 Agent 提供:
- 目标文件路径及其覆盖率中的
missing_lines - 读取源代码、现有测试并编写新测试的说明
- 下方的测试选择指南
子 Agent 应当:
- 读取源代码以及
lib/tests/streamlit/<path>/<module>_test.py处的现有测试 - 为以下内容编写测试:条件分支、错误处理、边界情况、异常路径
- 遵循
lib/tests/AGENTS.md:优先使用 pytest 风格的独立函数而非unittest.TestCase类,使用@pytest.mark.parametrize合并仅在输入/预期输出上不同的测试,添加 numpydoc 文档字符串和类型注解 - 运行新测试以验证其通过:
uv run pytest lib/tests/streamlit/path/to/module_test.py -v
第 4 步:验证并迭代
uv run pytest lib/tests/streamlit/path/to/module_test.py -v # Run new tests
make python-tests # Measure progress
重复第 2-4 步,直到覆盖率提升 ≥0.2%,然后运行 make check。
第 5 步:简化、审查并处理反馈
一旦所有测试通过且达成覆盖率目标:
- 运行
simplifying-local-changes子 Agent 来清理并简化代码改动。等待其完成。 - 运行
reviewing-local-changes子 Agent 来审查改动。等待其完成并阅读审查输出。 - 处理审查反馈:对每条建议,如果有效且能提升代码质量则实施;如果不适用或会导致过度设计,则跳过并简要说明理由。
- 运行 /checking-changes 以验证改动后一切仍能通过。
测试选择
应当测试: 条件逻辑、错误处理、边界情况(None、空、零、最大值)、公共 API 函数、复杂分支。
不要测试: 简单访问器、protobuf、实现细节、已被充分覆盖的代码。
覆盖率排除: 对确实不需要测试的代码谨慎使用 # pragma: no cover。始终附上理由(例如 # pragma: no cover - defensive):
- 无法在 CI 中运行的平台特定分支(
# pragma: no cover - platform-specific) - 永远不应执行的防御性代码(
# pragma: no cover - defensive) - 抽象方法桩或协议定义(
# pragma: no cover - abstract)
集成依赖: pyproject.toml 中 [dependency-groups] integration 下所列的包(例如 pydantic、sympy、polars、sqlalchemy)仅为集成测试安装,而非常规单元测试。编写使用这些包的测试时:
- 在测试函数内部导入它们,而非模块顶层
- 为测试添加
@pytest.mark.require_integration标记 - 这确保在集成测试环境之外运行时测试能优雅跳过
测试文件位置
lib/tests/streamlit/<package>/<module>_test.py 与 lib/streamlit/<package>/<module>.py 相对应
注意事项
-
质量 > 覆盖率数字——跳过那些无法捕获真实 bug 的测试
-
目标是按照
lib/tests/AGENTS.md实现 95%+ 的覆盖率 -
实现测试后使用
/checking-changes -
一些涉及外部库的代码路径(例如数据库连接器、可选依赖项)已被标记为
pytest.mark.require_integration的集成测试覆盖。这些集成测试不包含在make python-tests的覆盖率数字中。在分析缺失行时,先检查未覆盖的代码是否已被集成测试执行,然后再添加单元测试或# pragma: no cover注解。 -
本地与 CI 覆盖率差异: 版本相关的代码(Python 版本、库版本)或使用集成依赖项的代码在本地可能显示未覆盖,但在 CI 中已被测试和覆盖。示例:
- Python 版本特定分支(例如
if sys.version_info >= (3, 14)) 仅在匹配的 CI 任务中运行 - 库版本特定代码(例如 pandas 2.x 与 3.x 行为)在 CI 矩阵中覆盖
- 集成依赖项测试(
@pytest.mark.require_integration)在安装了这些包的单独 CI 任务中运行
在为这类代码添加测试或
# pragma: no cover之前,先确认它是否已在 CI 中被执行。 - Python 版本特定分支(例如