对于单元测试的定义,应该分成广义的和狭义两种。狭义的单元测试是指编写测试代码来验证被测试代码的正确性。广义的单元测试则是指小到一行代码的验证,大到一个功能模块的功能验证,从代码规范性的检查到代码性能和安全性的验证都包括在内,视单元的范围而定义。
1.单元测试由谁来做
关于单元测试应该由谁来做,存在两种截然不同的对立观点。一部分人认为单元测试既然是测试的一种类型,当然应该由测试人员负责;另外一部分人则认为,开发人员应该通过编写单元测试的代码来保证自己写的程序是正常工作的。
支持单元测试应该由开发人员执行的人认为,单元测试是程序员的基本职责,程序员必须对自己所编写的代码持有认真负责的态度。由程序员来对自己的代码进行测试的代价是最小的,却能换来优厚的回报,因为在编码过程中考虑测试问题,得到的是更优质的代码,这个时候程序员对代码应该做什么了解得最清楚。如果不这样做,而是一直等到某个模块崩溃时,程序员则可能已经忘记代码是怎样工作的,需要花费更多的时间重新弄清代码,即使这样也不一定能完全弄清楚,因此修改的代码往往不会那么彻底。
那些对程序员不应该测试自己代码的人认为,单元测试应该由测试人员来做。程序员通常都有爱护自己程序的潜在心理,不忍心对程序进行破坏性的测试,而且,程序员也缺乏像测试人员一样敏锐的测试思维,很难设计出好的测试代码。
说明:广义的单元测试不仅包括编写测试代码进行单元测试,还包括很多其他的方面,例如代码规范性检查,则完全可以由测试人员借助一些测试工具进行。
2.结对单元测试
关于单元测试应该由谁来完成,两部分人各持己见,争论了很多年,直到极限编程、测试驱动开发模式(TDD)出现,才使得两种意见得以综合考虑。
TDD把单元测试的地位提高到了史无前例的最高点,倡导测试先行、用测试驱动开发。测试是最好的设计,在编写代码之前就要把测试考虑清楚,这样在编写代码时才胸有成竹。有人举了两个工匠砌墙的例子来说明TDD。
工匠一的做法:先将一排砖都砌完,再拉上一根水平线,看看哪些砖有问题,再进行调整,如图所示。
工匠二的做法:先拉上一根水平线,砌每一块砖时,都与这根水平线进行比较,使得每一块砖都保持水平,如图所示。
TDD认为应该尽早进行测试,甚至在代码还没编写出来之前就先编写测试代码进行测试。如果是这样的话,很明显应该由开发人员进行单元测试了,程序员责无旁贷地要担负起单元测试的职责。
那么,反对这样做的人的观点是什么呢?测试人员应该与开发人员进行结对的单元测试,测试人员的优势是具有敏锐的测试思维和测试用例设计能力,应该充分利用测试人员的这些优点。一种可行的办法是:把两种观点结合在一起,让测试人员设计测试用例,开发人员编写测试代码实现测试用例,再由测试人员来执行测试用例。也就是说,让测试人员和开发人员结对进行单元测试,如图所示。
开发人员与测试人员在单元测试的过程中必须紧密地合作,一起讨论应该进行哪些测试以及怎样测试,应该添加哪些测试数据。
开发人员应该向测试人员提供程序的设计思路、具体实现过程以及函数参数等信息。
测试人员根据了解到的需求规格、设计规格来进行测试用例的设计,指导开发人员按照测试用例进行测试代码的设计。
测试人员运行开发人员编写的测试代码进行单元测试以及结果的收集与分析。或者利用单元测试工具让单元测试代码自动运行。
结对单元测试要求测试人员对需求的把握能力要强,而且对设计和编码过程有基本的认识。开发人员在结对单元测试中应能更好地按需求进行代码设计,同时也能从测试人员身上学到更多关于测试的知识,以便提高代码编写的质量和防止代码出错的能力。
延伸阅读
文章来源于领测软件测试网 https://www.ltesting.net/