name: 假驱动测试架构 description: 此技能应用于编写测试、修复bug、添加功能或修改网关层时。当您需要关于测试架构、使用假对象、实现ABC网关接口或理解防御深度测试策略的指导时使用。对于维护测试质量和理解不同类型测试所属位置至关重要。
基于假的Python测试架构
使用此技能当:编写测试、修复bug、添加功能或修改Python项目中的网关层。
先决条件:对于Python代码标准,请先加载dignified-python-313技能。此技能专注于测试架构,而非Python语法。
概述
此技能为Python应用程序提供防御深度测试策略,包含五层:
┌─────────────────────────────────────────┐
│ 第5层:业务逻辑集成测试 (5%) │ ← 真实系统的冒烟测试
├─────────────────────────────────────────┤
│ 第4层:业务逻辑测试 (70%) │ ← 基于假的测试(大多数测试)
├─────────────────────────────────────────┤
│ 第3层:纯单元测试 (10%) │ ← 零依赖,隔离测试
├─────────────────────────────────────────┤
│ 第2层:集成健全性测试 (10%)│ ← 使用模拟进行快速验证
├─────────────────────────────────────────┤
│ 第1层:假基础设施测试 (5%)│ ← 验证测试替身工作
└─────────────────────────────────────────┘
理念:在快速内存假的之上广泛测试业务逻辑。少量使用真实实现进行集成验证。
术语说明:“网关层”(也称为适配器/提供者)指围绕重量级外部API(数据库、文件系统、HTTP API、消息队列等)的薄包装器。模式比名称更重要。
快速决策:我应该阅读什么?
添加功能或修复bug?
→ 先阅读quick-reference.md,然后workflows.md#adding-a-new-feature
需要了解测试放置位置?
→ 阅读testing-strategy.md
处理Python特定模式?
→ 阅读python-specific.md
添加/更改网关接口?
→ 阅读gateway-architecture.md,然后workflows.md#adding-a-gateway-method
创建后端(网关之上的高层抽象)?
→ 阅读gateway-architecture.md#gateways-vs-backends - 后端组合网关,但不包含假对象
需要实现特定模式(CliRunner、构建器等)?
→ 阅读patterns.md
不确定是否正确操作?
→ 阅读anti-patterns.md
只需快速查阅?
→ 阅读quick-reference.md
何时阅读每个参考文档
📖 gateway-architecture.md
阅读当:
- 添加或更改网关/ABC接口
- 理解ABC/真实/假/试运行模式
- 需要网关实现示例
- 想了解网关是什么(以及为什么它们很薄)
- 创建后端(组合网关的高层抽象)
内容:
- 网关类是什么?(命名:网关/适配器/提供者)
- 四种实现(ABC、真实、假、试运行)
- 每种示例代码
- 何时添加/更改网关方法
- 设计原则(保持网关薄)
- 常见网关类型(数据库、API、文件系统、消息队列)
- 网关vs后端 - DI边界的关键区别
📖 testing-strategy.md
阅读当:
- 决定测试放置位置
- 理解五层测试
- 需要测试分布指导(5/70/10/10/5规则)
- 想知道哪层测试什么
内容:
- 第1层:假对象的单元测试(验证测试基础设施)
- 第2层:使用模拟的集成健全性测试(快速验证)
- 第3层:纯单元测试(零依赖,隔离测试)
- 第4层:基于假的业务逻辑测试(大多数测试)
- 第5层:业务逻辑集成测试(真实系统的冒烟测试)
- 决策树:我的测试应放在哪里?
- 测试分布示例
📖 python-specific.md
阅读当:
- 使用pytest夹具
- 需要Python模拟模式
- 测试Flask/FastAPI/Django应用
- 理解Python测试工具
- 需要Python特定命令
内容:
- pytest夹具和参数化
- 使用unittest.mock和pytest-mock进行模拟
- 测试Web框架(Flask、FastAPI、Django)
- Python测试命令
- 测试中的类型提示
- 测试实用程序的Python打包
📖 workflows.md
阅读当:
- 添加新功能(逐步)
- 修复bug(逐步)
- 添加网关方法(完整清单)
- 更改接口(需要更新什么)
- 管理试运行功能
内容:
- 添加新功能(TDD工作流)
- 修复bug(重现→修复→回归测试)
- 添加网关方法(8步清单与示例)
- 更改接口(更新所有层)
- 管理试运行功能(包装模式)
- 使用构建器模式测试
📖 patterns.md
阅读当:
- 为假对象实现构造函数注入
- 为假对象添加突变跟踪
- 使用CliRunner进行CLI测试
- 使用构建器构建复杂测试场景
- 测试试运行行为
- 需要特定模式代码示例
内容:
- 构造函数注入(如何及为何)
- 突变跟踪属性(只读访问)
- 使用CliRunner(而非子进程)
- 复杂场景的构建器模式
- 模拟环境模式
- 错误注入模式
- 试运行测试模式
📖 anti-patterns.md
阅读当:
- 不确定方法是否正确
- 想避免常见错误
- 审查代码中的不良模式
- 调试测试为何慢/脆弱
内容:
- ❌ 测试推测性功能
- ❌ 测试中硬编码路径(灾难性的)
- ❌ 未更新所有层
- ❌ 单元测试中使用子进程
- ❌ 网关类中的复杂逻辑
- ❌ 假对象的I/O操作
- ❌ 测试实现细节
- ❌ 网关测试覆盖率不完整
📖 quick-reference.md
阅读当:
- 快速查阅文件位置
- 查找示例测试以参考
- 查找常见夹具
- 需要命令参考
- 需要测试分布指南
内容:
- 决策树(在哪里添加测试)
- 文件位置图(源码+测试)
- 常见夹具(tmp_path、CliRunner等)
- 常见测试模式(代码片段)
- 示例测试以参考
- 有用命令(pytest、ty等)
- 添加网关方法的快速清单
按任务快速导航
我正在添加新功能
- 快速开始:
quick-reference.md→ 决策树 - 逐步指南:
workflows.md#adding-a-new-feature - 模式:
patterns.md(CliRunner、构建器) - 避免:
anti-patterns.md(推测性测试、硬编码路径)
我正在修复bug
- 逐步指南:
workflows.md#fixing-a-bug - 模式:
patterns.md#constructor-injection-for-fakes - 示例:
quick-reference.md#example-tests-to-reference
我正在添加/更改网关方法
- 理解:
gateway-architecture.md - 逐步指南:
workflows.md#adding-a-gateway-method - 清单:
quick-reference.md#quick-checklist-adding-a-new-gateway-method - 避免:
anti-patterns.md#not-updating-all-layers
我不知道测试应该放在哪里
- 决策树:
quick-reference.md#decision-tree - 详细指南:
testing-strategy.md - 示例:
quick-reference.md#example-tests-to-reference
我需要实现一个模式
- 所有模式:
patterns.md - 示例:
quick-reference.md#common-test-patterns
我认为我做错了什么
- 反模式:
anti-patterns.md - 正确方法:
workflows.md
视觉层指南
┌──────────────────────────────────────────────────────────────┐
│ 第5层:业务逻辑集成测试 (5%) │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ 真实数据库、文件系统、API、实际子进程 │ │
│ │ 目的:冒烟测试,捕获集成问题 │ │
│ │ 何时:稀疏,用于关键工作流 │ │
│ │ 速度:秒每测试 │ │
│ │ 位置:tests/e2e/ 或 tests/integration/ │ │
│ └──────────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────┐
│ 第4层:业务逻辑测试 (70%) ← 大多数测试在此 │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ 假数据库、假API客户端、假文件系统 │ │
│ │ 目的:广泛测试功能和业务逻辑 │ │
│ │ 何时:对每个功能和bug修复 │ │
│ │ 速度:毫秒每测试 │ │
│ │ 位置:tests/unit/、tests/services/、tests/commands/ │ │
│ └──────────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────┐
│ 第3层:纯单元测试 (10%) │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ 零依赖,无假对象,无模拟 │ │
│ │ 目的:测试隔离实用程序和辅助工具 │ │
│ │ 何时:用于纯函数、数据结构、解析器 │ │
│ │ 速度:毫秒每测试 │ │
│ │ 位置:tests/unit/ │ │
│ └──────────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────┐
│ 第2层:集成健全性测试 (10%) │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ 真实数据库带模拟连接 │ │
│ │ 目的:快速验证,捕获语法错误 │ │
│ │ 何时:当添加/更改真实实现时 │ │
│ │ 速度:快速(模拟的) │ │
│ │ 位置:tests/integration/test_real_*.py │ │
│ └──────────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────┘
┌──────────────────────────────────────────────────────────────┐
│ 第1层:假基础设施测试 (5%) │
│ ┌──────────────────────────────────────────────────────────┐ │
│ │ 测试假数据库本身 │ │
│ │ 目的:验证测试基础设施可靠 │ │
│ │ 何时:当添加/更改假实现时 │ │
│ │ 速度:毫秒每测试 │ │
│ │ 位置:tests/unit/fakes/test_fake_*.py │ │
│ └──────────────────────────────────────────────────────────┘ │
└──────────────────────────────────────────────────────────────┘
关键原则
- 薄网关层:包装外部状态,将复杂性推至业务逻辑
- 基于假的快速测试:70%的测试应使用内存假对象
- 防御深度:假→健全测试→纯单元→业务逻辑→集成
- 测试您正在构建的内容:无推测性测试,仅活动工作
- 更新所有层:更改接口时,更新ABC/真实/假/试运行
- 网关vs后端:网关有假对象;后端组合网关,但不包含假对象
层选择指南
区分第3层(纯单元)与第4层(业务逻辑):
-
第3层(纯单元测试):零依赖 - 无假对象,无模拟,无外部状态
- 测试字符串实用程序:
sanitize_branch_name("feat/FOO")→"feat-foo" - 测试解析器:
parse_git_status("## main")→{"branch": "main"} - 测试数据结构:
LinkedList.append()无任何外部依赖
- 测试字符串实用程序:
-
第4层(业务逻辑测试):使用假对象处理外部依赖
- 测试命令:
create_worktree(fake_git, name="feature") - 测试工作流:
submit_pr(fake_gh, fake_git, ...) - 测试协调多个集成的业务逻辑
- 测试命令:
如果您的测试导入假对象,它属于第4层,而非第3层。*
默认测试策略
不确定时:
- 为业务逻辑编写基于假的测试(第4层)
- 为无依赖的实用程序/辅助工具编写纯单元测试(第3层)
- 使用
pytest带夹具 - 使用
tmp_path夹具(而非硬编码路径) - 遵循
quick-reference.md中的示例
总结
快速任务:从quick-reference.md开始
理解:从testing-strategy.md或gateway-architecture.md开始
逐步指导:使用workflows.md
实现细节:使用patterns.md
验证:检查anti-patterns.md
Python特定:检查python-specific.md