Perl 测试模式
使用 Test2::V0、Test::More、prove 和 TDD 方法论为 Perl 应用程序提供全面的测试策略。
何时激活
- 编写新的 Perl 代码(遵循 TDD:红、绿、重构)
- 为 Perl 模块或应用程序设计测试套件
- 审查 Perl 测试覆盖率
- 设置 Perl 测试基础设施
- 将测试从 Test::More 迁移到 Test2::V0
- 调试失败的 Perl 测试
TDD 工作流程
始终遵循 RED-GREEN-REFACTOR 循环。
Test::More 基础
标准的 Perl 测试模块 —— 广泛使用,随核心发行。
基本断言
SKIP 和 TODO
Test2::V0 现代框架
Test2::V0 是 Test::More 的现代替代品 —— 更丰富的断言、更好的诊断和可扩展性。
为什么选择 Test2?
- 使用哈希/数组构建器进行卓越的深层比较
- 失败时提供更好的诊断输出
- 具有更清晰作用域的子测试
- 可通过 Test2::Tools::* 插件扩展
- 与 Test::More 测试向后兼容
使用构建器进行深层比较
子测试
使用 Test2 进行异常测试
测试组织与 prove
目录结构
prove 命令
.proverc 配置
夹具与设置/拆卸
子测试隔离
共享测试助手
将可重用的助手放在 t/lib/TestHelper.pm 中,并通过 use lib 't/lib' 加载。通过 Exporter 导出工厂函数,例如 create_test_db()、create_temp_dir() 和 fixture_path()。
模拟
Test::MockModule
对于轻量级的模拟对象,使用 Test::MockObject 创建可注入的测试替身,使用 ->mock() 并验证调用 ->called_ok()。
使用 Devel::Cover 进行覆盖率分析
运行覆盖率分析
集成测试
对数据库测试使用内存中的 SQLite,对 API 测试模拟 HTTP::Tiny。
最佳实践
应做事项
- 遵循 TDD:在实现之前编写测试(红-绿-重构)
- 使用 Test2::V0:现代断言,更好的诊断
- 使用子测试:分组相关断言,隔离状态
- 模拟外部依赖:网络、数据库、文件系统
- 使用
prove -l:始终将 lib/ 包含在@INC中 - 清晰命名测试:
'user login with invalid password fails' - 测试边界情况:空字符串、undef、零、边界值
- 目标 80%+ 覆盖率:专注于业务逻辑路径
- 保持测试快速:模拟 I/O,使用内存数据库
禁止事项
- 不要测试实现:测试行为和输出,而非内部细节
- 不要在子测试之间共享状态:每个子测试都应是独立的
- 不要跳过
done_testing:确保所有计划的测试都已运行 - 不要过度模拟:仅模拟边界,而非被测试的代码
- 不要在新项目中使用
Test::More:首选 Test2::V0 - 不要忽略测试失败:所有测试必须在合并前通过
- 不要测试 CPAN 模块:相信库能正常工作
- 不要编写脆弱的测试:避免过度具体的字符串匹配
快速参考
常见陷阱
忘记 done_testing
缺少 -l 标志
过度模拟
模拟依赖项,而非被测试的代码。如果你的测试只验证模拟返回了你告诉它的内容,那么它什么也没测试。
测试污染
在子测试内部使用 my 变量 —— 永远不要用 our —— 以防止状态在测试之间泄漏。
记住:测试是你的安全网。保持它们快速、专注和独立。新项目使用 Test2::V0,运行使用 prove,问责使用 Devel::Cover。


