所谓单元测试,即对软件的各个组成“零件”进行测试,也就是对软件中可测试的最小模块进行测试。这种基本组成单元大致分成两种,传统软件中指的是模块,也就是函数,面向对象的软件工程中,指的是类的方法。
很多人认为单元测试浪费时间,因为软件工程中,我们肯定是由不同的人负责不同的部分,假如我们好不容易把不同的部分分别打造完毕,这时候心里最想的一件事肯定是把所有的东西合在一起,这是一步质的飞跃,很多人迫不及待,因为这样就可以看到实际的系统运行。
但是在那之前,我们必须冷静下来考虑一件事:就算最优秀的编程人员也不敢说自己的程序没有问题,所以,我们在把所有东西“熔”在一起之前,是不是应该确保自己手里要交上去的东西没有问题。在换一个角度想,假如真的有bug,那将来集成之后,肯定是能测出bug来的,肯定还要回头寻找,正常人眼里,在一个小的模块里面找bug可比在一个“大熔炉”里面找容易多了。
而且,我们要承认一件事,有时候,把所有东西都合在一起之后,有些错误查不出来,因为合成一个庞大的系统之后,测试用例要想覆盖每个单元中的所有路径是很困难的,所有真的有可能一些缺陷查不出来,然后,将来的某天,我们的维护人员要大发雷霆。
所以,单元测试不是无用的,其作用是大大的。
然后,我们就来看看究竟如何单元测试。
单元测试的关键是构造单元测试的环境,何为单元测试的环境呢,那就是,因为我们只是测试单个模块,无法得到整个软件的代码,而本模块是要和其他模块由联系的,我们的任务就是要人工模拟出其他的模块,能完成和本模块的通信工作。
这种模拟的模块分为两类:
1、本模块的下层模块,目的是实现被测模块的接口,也就是被本模块调用的模块,名为桩模块。
2、本模块的上层模块,目的是实现被测模块的“主函数”,也就是调用本模块的模块,名为驱动模块。
其实虽然这是关键,但是,由于本身这些模块是对其他模块的模拟,也就是说,用完一次就丢,所以,我们需要尽量少做这种模块。而且,桩模块一般比驱动模块复杂,所以应该追求整体上驱动模块较多。
然后是一些测试是要重点关照的内容
1、模块的接口。重点便是接口的参数个数,类型,顺寻等属性,包括驱动模块调用本模块的函数和本模块调用子模块的接口。
2、局部数据结构。这个就是检查模块内的数据结构正否正确,避免有一些什么变量没有初始化,变量类型不正确的错误。
3、路径测试。这个部分是测试一些运算的正确性,因为有时候会有数据溢出,运算顺序不正确(运算符的顺序不对),数据精度不正确等问题。
4、错误处理测试。这个是测试程序在出错之后能否正常处理。这个其实是我们很容易忽略的,因为我们在编程时自然而然的想到程序正常运行的情况,而忽略了异常,所 以,很多错误没有理会;或者我们处理的方法根本不合理,需要更精确的处理;又或者我们对错误本身的判断就有问题。
5、边界测试。有些程序对边界值得处理有待商榷,比如循环中跳出条件中的n,条件判断语句中跳转的界限,其实边界值问题围绕的就是边界值等或不等的问题,把这个考 虑清楚事情就简单多了
单元测试过程中,一般是白盒测试为主的,因为测试是开发人员自己来,或者开发人员和测试人员合作来进行,所以可以拿到第一手的代码,而且,由于是本人就在,白盒测试也更方便。当然,适当的黑盒也必要,因为,可能有人不看文档,直接就自己写程序,结果程序的功能有偏差。
总之,单元测试是很实用的,而且,一般它是最早进行的,我们应该看重它价值。