单元测试检查清单:让你的测试保持有效,避免大的错误

jopen 10年前

单元测试是测试你代码的一些常用方法集. 一般的操作步骤如下:

  1. 先写北侧类的API

  2. 测试对应API的方法名

  3. 实现对应测试API的方法体

  4. 运行单元测试

为什么需要单元测试? 它可以测试现有的以及未来的功能模块. 保证代码质量. 它规范你书写具有可测性,低耦合的代码.这比手工回归测试廉价的多. 它将提高代码可行度.协助团队工作.

为啥需要个检查列表? 单元测试在实际操作时可能要复杂一点. 它需要你考虑清楚整个待测对象的框架. 但测试本身应该简单,直接,易用和易维护. 对于测试的开始点和结束点也要十分清楚.

使用这个检查列表能帮助你确保测试范围的有效性. 切记: 该列表能帮助你绕开那些明显的错误,但有前提:

□  一个测试类对应一个被测类.

  • o  你要测试的是一个已声明的类的正确性.

□  一次只测试一个方法体.

  • o  私有方法不需要测试! 它们是被封装起来的.

□  测试的方法名和变量都是显示定义的.

  • o  比如,将预期结果保存到 expectedFoo 变量就比 foo好得多. 如果要测试很多复合结果,可以使用组合的名称inputValue_NotNull, inputValue_ZeroData, inputValue_PastDate, etc. (取决于你的代码规范).

□  测试用例易于理解.

  • o 后来的使用者将会很容易理解测试代码的大意而无需关注太多的具体实现. 这能帮助他们在调试之前知道工作的大概内容.

□  测试用例符合代码整洁规范.

  • o  测试用例中不要包含流程控制语句 (switch, if, 等.). 好的用例就是很直接的数据准备,结果验证过程.如果场景需要,可以配上测试桩来优化代码结构. 对于多场景测试,书写多个对应的测试用例 (一一对应).

  • o  比如,一个测试用例代码长度最好在 – 1 到20行左右.如果测试代码太长,考虑拆开成独立的小测试集,以避免搅在一起.

□  测试用例最好验证预期的异常.

  • o  Java里用 @Test(expected=MyException.class).

□  测试用例最好不要连接到数据库.

  • o或者说,如果测试中需要连接数据库操作,就使用mock “在每次新的测试开始注意测试时的数据库连接状态”连接,断开  (使用 Setup/Teardown).

□  测试用例最好不要连接网络资源.

  • o 测试某个方法时没办法确保第三方的网络设备的有效性 (使用mocks).

□  测试用例需要注意边际效应,极限值 (max, min) 和null的处理(就算是在异常中抛出的也要注意).

  • o就算在测试里这些内容不需要被维护,我们也要确保这些问题不会出现.

□ 测试用例不论在任何时候任何地方都无需人工干预来执行.

□  测试用例测试了当前的代码但也能很容易的测试将来实现的代码.

  • o  测试就是为了确保代码的正确演变.如果没法易于扩展,那它就成了负担. (很多人不写单元测试用例就是这个原因.)

□  测试用例具有一致性.

  • o  在Java: 别使用 Date()作为被测方法的输入数据,最好使用Calendar (别忘了时区配置). 再比如: 用name = “Smith”; 不要用 name = “name”; 或是name = “test”;

□  测试用例使用mock来模拟复杂的代码结构或方法体.

  • o  记住一次只测试一个类.

    o  不要在自己的类中测试第三方的类库. 类库的测试交给它们自己的测试 (这也是鉴别类库优劣的一条准则).

□  不要注释掉测试用例 @ignored . 切记. 切记.

□  测试帮助我确保了整体的架构设计.

  • o  如果有那个方法没办法被测试,说明设计的有问题.

□ 我的测试可以运行在任何平台,而非指定目标平台

  • 别指望一个特定的设备或硬件配置。否则你的测试会使迁移更困难,这里鼓励禁用它们。

□ 我的测试像闪电一般快!

  • 慢的测试不应该把你拖垮。速度鼓励你经常启动您的测试。它还有助于减少持续集成系统上的构建时间。

  • 使用测试运行程序,允许您在写测试时一次启动一个测试。要小心使用“delay”和“sleep”,比如只有在一些边缘情况下,像等待通知或基于时钟的方法。