因为产品的测试工程极不好用,又慢、又大、又乱、……关键是没有哪个版本经理愿意在测试代码上耗费人力。偶然看到此书介绍,以为找到真经,跑到公司图书馆取来研读。速速浏览一下,感觉远远没有想象中管用,虽然封面也标明该书获了美国生产力大奖,但和《敏捷软件开发原则、模式与实践》相比不是一个档次,we can't judge a book by its cover。内容大都熟悉,所以本书尽管很厚,没有让人拍案叫绝之处。中文翻译我不满意,太生硬,不少关键术语都不是研发一线的惯用语(例如“新鲜夹具”), 直接读英文不比中文难读。 xUnit.Test.Patterns.Refactoring.Test.Code.May.2007
1、Setup方法的滥用
xUnit提供了Setup方法,有的初学者不知道有这么个好东西,有的知道了但没有将测试方法合理地分组就拿来用,效果不好。
本书打了个比方:“如果有了锤子,什么东西看起来都像是钉子!”
除了Setup,类似的还有mock。Mock是个好东西,但是如果你看到一个测试用例使用了25个mocker(…),会有什么感觉?这是我在我们产品测试代码中见过的真实例子,思索了5秒后我把那个测试用例直接注掉了。
还有一个值得一提的例子就是面向对象中的继承,初学继承者往往什么都想重用。
可谓“少年不知愁滋味,为赋新词强说愁。”
2、如何减少测试码复制?
经常看到一段段相似的测试用例,显然是copy-paste的,特别是在结果验证那几行。有这么几招可以消除重复:
使用预期对象;
自定义断言;
封装验证方法;
参数化和数据驱动;
3、如何编写意图明显的测试码?
写产品代码前先写测试码;
写测试码时先写断言;
标识符命名要明确体现意图;
4、提倡每个测试验证一种条件的原因是方便定位。
5、如何设计测试用例类?
三种方法:
(1) 每个类(模块)一个测试用例类;
(2) 每种特征一个测试用例类;
(好处是易于理解业务场景,使用合适的命名);
(3) 每个前置条件一个测试用例类;
(利于将前置条件放到Setup方法,但又不滥用Setup。)
以上,没有最好,只有最合适。
“最佳实践就是最适合于特定环境的实践。”
6、关于代码的坏味道
味道1:长测试
难以理解和维护,不能充当文档角色。
导致长测试的典型原因:
(1) 职责不单一。验这验那,验太多功能。
(2) 有神秘访客。前置条件与验证逻辑的因果关系不直观、不明显,依赖于神秘的外部资源(如文件)。
(3) 过多的前置条件。
(4) 在读者关心的层次放置了不相关的信息(变量、值);
(5) 硬编码的值;
(6) 间接测试;
味道2:难以测试的代码
如GUI、多任务、报文等。
对于高耦合的代码,建议用mock解决。
对于任务体代码,建议封装任务体代码,对封装不分进行测试。
味道3:测试码复制
味道4:产品中的测试逻辑
7、关于行为的坏味道
味道1:一个测试方法内堆积多个断言,减少用例的数量
味道2:不稳定的测试,有时成功,有时失败
原因可能是测试间相互耦合,共享条件,或自身状态迁移。
味道3:手动调试,如单步跟踪,看内存
味道4:缓慢
原因:编译慢、测试分类或头文件依赖不合理导致不必要的联动、延时、大数据拷贝。
影响明显直接徒增成本,降低团队生产率。
8、项目的坏味道
味道1:开发人员不DT
时间紧:无暇顾及测试重构;
技能不足:测试设计及TDD经验欠缺;
味道2:搞维护成本
表面战斗力、覆盖率上升,实际团队生产率下降,耗费大量精力。
味道3:补用例
为什么不安排在项目前期先写用例?
味道4:用#if 0大量注掉难以维护的用例
这些难以维护的用例大多是补出来的。
味道4:转测试后发现本可通过LLT轻易发现的缺陷