有一种说法:程序员测本身的代码效果很差,由于测试是找错,程序员不肯意去证实本身是错的,别人测效果才好,对吗?这种说法是根本错误的,误导了无数人。正好相反,单元测试要本身测效果才好,别人测则几乎没有效果,除非有函数级的详细文档。程序员
单元测试的三种方式:程序员编码同时测试、程序员编码后测试、由别人测试,成本的比例大概为1:3:5,测试效果的比例大概为5:3:1。这是指通常的开发过程,其特征是没有函数级的详细文档。ide
咱们先来看看你们耳熟能详的几个概念:需求、设计、实现。需求是“要作什么”,设计是“具体怎么作”,实现是“作出来”。写一个函数,无论写不写文档,需求、设计、实现仍然是必经的过程,只不过面对的目标很小而已。函数
写一个函数,程序员要想清楚“要作什么”和“具体怎么作”,这是所想。显然,所想的就是需求和设计。把代码写出来则是实现,这是所作。单元测试
若是在写代码同时测试,测试用例必定是依据“所想”而设计的,测试的结果是验证“所作”是否符合“所想”,也就是说,测试的结果是:验证明现是否符合需求。这种方式,需求是清晰的(虽然只是在程序员的脑子里),因此效果最好,而用例只需根据“所想”直接设计就行,还能够利用测试来驱动开发,因此成本最低。测试
程序员编码后测试,“所想”已经忘了一部分,要根据代码来“恢复”,可是不可能所有“恢复”。测试的结果,有多是“验证明现是否符合需求”,也有可能不是,因此效果会打折扣,因为要花时间来“恢复”所想,且不能利用测试来驱动开发,因此成本也会高得多。编码
由别人测试,用例设计的依据是什么?除非程序员在编码时把“所想”记录下来,造成函数级的详细文档,不然,“别人”只能读代码来肯定需求,实际上,这个“需求”是实现自己,测试的结果是:验证明现是否符合实现,俗称“跟着代码走”,这样的测试有什么意义?成本方面,须要读代码来肯定需求,无疑很费时间,因此成本最高。设计
举个简单的例子来讲明。程序员要一个加法函数,结果写成了:code
int fun(inta, int b) { return a - b; };
编码时测试,程序员必定知道本身要写的是加法函数,用例为a=1; b=2;ret==3,固然能发现错误。blog
编码后测试,程序员有可能想起这是加法函数,测试能发现错误,也有可能忘了,读代码后认为这是一个减法函数,这样测试就没意义了。ip
别人测试,只能读代码,认为是减法函数,测试没意义。
固然,实际的情形不会那么单纯,代码可能有一些注释,“别人”也许能了解代码的大体需求,因此“别人”测试也会有一些效果,可是,单元测试主要作的,是找出实现与需求之间的细微误差,例如,一些输入下代码是正确的,一些输入下,代码有问题(未分类处理这些输入或处理错误),“别人”即便可以了解代码的大体需求,也难于了解所有需求,测试效果老是颇有限的。
也许有人会说,边编码边测试,虽然依据的是代码的需求(小需求),可是这个需求是否符合系统的总体需求(大需求)呢?换几句话说,原本这个函数要作的是A功能,但程序员所想的是B功能,那测试不是没有意义吗?1、由别人测试,跟着代码走,这个问题一样存在;2、这种错误在集成后很容易发现;3、这种错误不多。用小需求不必定符合大需求来否认程序员测试本身的代码,那就是因噎废食了。
总之,通常情形下,程序员编码同时测试、程序员编码后测试、由别人测试,三种方式的成本的比例大概为1:3:5,测试效果的比例大概为5:3:1。这个比例只是定性,我没法精确证实,信不信由你,反正通过十多年的实践,我是信的。