不写单元测试的厨师不是好司机
好吧,我承认题目就是个噱头,无聊的时候自娱自乐是一种病,得治!
今天要说的话题就是单元测试。从题目说起,厨师和司机都是非常常见的职业,在他们的职业生涯中有着各自的单元测试(其实单元测试无处不在,这里只是举一个简单的例子而已,请大家领会精神)。
菜桌上的每一道菜所经历的每个步骤都有单元测试。从种菜开始菜的种子要经过精心挑选的必须成活率符合标准才会发放到各地的种子站。然后农民伯伯辛苦种菜拉到菜市场,到了菜市场想卖出去必须得有营业执照(不怕城管的好汉们除外)还得有卫生许可等等吧,每一步都是一个单元测试。相比而言那种自产自销的农家作业要么规模小要么质量达不到保证。
和司机有关的事物更是如此,每辆在马路上行驶的汽车它们的每个螺丝钉都需要经过检验,最后车会被合格的部件组合到一起。司机的驾照也是一个“单元测试”,社会是复杂的不能让不安全的因素影响了其他人所以保证(或者说尽全力保证)每个人的质量是保证整个社会交通安全的重要手段。
不单单这两个职业其他的一切一切都是这个道理,要想保证一个复杂的工程成功那么最有效的办法就是将这个工程分工,然后保证每一步每一部分都是成功的,如此一来这个复杂的事情就有可能会成功,这里仅仅是有可能而已,按照测试原理的说法就是,单元测试成功并不代表回归以及集成测试会成功。
所以这么说来单元测试是成功不可或缺的一步,是保证成功的重要一个环节。
几点要求:
每个类都是应该可以被测试的,而且是容易被测试的。这就要求编码的时候要考虑单元测试,而不是单纯为了实现功能而实现功能。
单元测试覆盖率是应该保证的,边缘测试特殊值测试、以及条件分支的测试、异常捕获后处理的测试等等这些是保证覆盖率需要特别注意的地方。
如果用到了容器的东西,最著名的是EJB当中用到了服务器当中的东西,那么该如何测试呢,现在方法有两种,第一种是尽量摆脱容器写可测试的类。第二种是建立模拟的容器,将容器中的东西模拟进去并且赋值,最终判断是否为预期输出。
单元测试往往进行是不顺利的,因为很多coder不会写单元测试更不会去考虑写单元测试的人的感受,所以很多void返回值的方法、很多借用容器变量的方法遍布类中,导致测试困难。在测试这些方法的时候需要变通一下,比如最简单的就是测试list的add方法,返回值是void怎么办,可以放进去然后拿出来看看是否放了进去,也可以放进去之前看一下list的大小,然后放进去重新看一下大小。总之测试的意思就是代码有没有正常工作,无论是直接证明还是间接的证明,只要你的理由充分的(或者必要的)那么这个测试就可以勉强说成是成功的。
目前为止单元测试没有提升到一个高度,因为从网上找一个单元测试的教程都找不到,找几本单元测试书都很困难。开发过程中开发团队要么没有单元测试,要么就是仅仅是一个摆设,这就说明很少有人去关心单元测试,也说明单元测试还是很有难度的。后面几篇博客将详细介绍笔者在开发过程中如何做单元测试的,希望对读者有用。