近期, 给项目化开发人员做技能培训时, 整理了一下团队在 DOD 中对于单元测试最佳实践和要求, 作为单元测试规范, 如下:
原则开发人员在编写代码过程中需要恪守的基本准则, 在日常工作中需要在基本原则的指导下完成代码开发任务
规则开发人员在日常开发过程中必须严格遵守的规则, 这是系统代码得以正常稳定运行的基础, 是以团队合作方式进行软件开发的基本保证
建议建议部分提出的内容, 希望员工能够尽量遵守, 这些内容是经验丰富的开发人员在长期开发中积累的宝贵经验教训, 有助于编写出高质量的代码
原则 1 遵循 TDD 三原则 (定律)
- 没有用例失败时, 不要写产品代码
- 当有用例失败时, 不要写更多的用例
- 仅写让用例通过的代码
原则 2TDD 遵循测试的 FIRST 原则
F(Fast): 测试要能快速运行
I(Isolate): 测试用例要独立, 不能相互依赖
R(Repeatable): 测试要可以重复运行
S(Self-verifying): 测试会自己检查产出
T(Timely): 测试要及时做, 与写代码紧密相连
原则 3TDD 是开发行为, 是 DOD
TDD 是开发必须的基本技能
交流的基本语言
DoD - 开发完成的定义, 团队成员认可, 不断扩充
原则 4 代码是债务, 单元测试用例也是, 优先修复并且不断重构
规则 1 每一个用例测试一个概念 / 功能
测试用例遵循 SRP 当测试失败时, 很容易知道用例失败的原因
规则 2 测试名称遵循 BDD(Gievn-When-Then) 书写模型: Given/When/Then
假如 [当测试开始时, 系统所处状态的一些重要特征], 当 [用户执行某些动作后], 那么 [系统新的状态的一些特征]
TEST(RecurrNonProrateStateChangeReactiveTest, GivenFeeIs100$PerMonthAndBenefit100SMS_WhenReactiveAt20thJanuary_ThenDeduct100$AndBenefit100SMS)
规则 3 测试用例按照构造数据 / 执行功能 / 检测结果进行代码分块
用例编写也遵循 BDD(Gievn-When-Then) 书写模型并按照构造数据 / 执行功能 / 检测结果分块
规则 4 将具有相同测试环境的用例放在同一个测试套件中
将构造测试环境及清理测试环境的代码分别放在 Setup 及 Teardown 中, 可以消除重复的代码, 实现代码的最大可复用性
建议 1 用例业务场景复杂时可以通过注释提高可读性
除了用例名称, 可以通过注释可以详细描述用例的测试场景
用例注释
建议 2 通过用例套件来测试跨进程间的协议正确性
例子: SY 测试时, OCPro 生成内部消息, 转发给你进程 sydealsnr 来处理可以在一个套件来测试这两个用例, 并严重接口
- TEST_F(TTest_OcproSendSNRMsg, GivenTriggerPCRF_WhenOcproUSURating_ThenOcproSendSnrMsgSucessful)
- TEST_F(TTest_OcproSendSNRMsg, GivenSySpInfo_WhenSyDealSnrReceiveMsgFromOcpro_ThenReturnSnrAVPSucessful)
建议 3 用例代码和业务代码独立, 并且建立对应目录, 在内部可以按照业务分层建立目录
建议 4 每个用例套件一个独立的 CPP 文件用例公用代码文件以 gtest_来区分业务代码
建议 5 用例数据保持无关, 保证可以并行执行, 提高运行速度
因为历史原因或者特殊原因, 无法做到数据独立, 用例非 utest_开头, 优先串行执行; 文件名以 utest_前缀的用例程序并行执行
建议 6 为了方便验证功能, 某写特殊场景也可以直接测试 private 和 protected 函数
在对应头文件包含前加上转移说明
- #include "gtest/gtest.h"
- #define private public
- #define protected public
- #include "DAOInterface.h"
因为每个未证明正确的代码都是有嫌疑的, 因此新增单元测试用例的最佳时机就是新增功能和修复功能之前
来源: http://www.jianshu.com/p/ac0a2617c237