明晰单元测试

最近,身边的一位朋友由于须要在其单位与同事分享单元测试(Unit Test,UT)方面的知识,邀我对他所准备的PPT进行审阅。在审阅的过程当中我发现,他在PPT中指出:“实际工做中,写好程序后对程序功能的调试就是一种单元测试”。因为我知道这位朋友并无运用单元测试的经验,因此我问到:“你的这一认识是从哪里得到的?”,朋友答曰:“从网上搜来的”。无独有偶,这两天我在微博上看到了对单元测试类似的理解:“写好程序,编译完,跑一跑,看看写得对不对,这就是最简单的UT啊!”
 
对于我这混迹于软件行业超十载,且在工做中能常常娴熟运用单元测试的“老鸟”来讲,看到这样的理解实在是hold不住了,以为颇有必要写一篇文章以正视听(但愿后面的人能“搜”到这篇文章)。
 
之因此要作“以正视听”这件事,是由于我担忧上面的解释让新人或没有单元测试经验的人产生一种幻觉 ——“哇,好赞诶,原来我天天都在作单元测试!”这种幻觉带的后果,是这些人不去作真正的单元测试,且别人在说单元测试如何如什么时候,他殊不知所云。
 
若是要用不会产生争议的文字解释单元测试,我想我不必定能写得比维基百科上的好(点击 这里 ,或许参考个人《 专业嵌入式软件开发 》一书更好),那请容许我从特色的角度对之加以解释。首先,单元测试必定要写测试代码。测试代码并不会最终成为软件产品的一部分,测试代码经过实现各类不一样测试用例的方式,检查被测代码(最终成为软件产品的一部分)的行为是否如程序员所但愿的那样。读者不难想象,测试用例中须要构建大量被测代码所需的参数、环境等(体力活)。
 
其次,为了简化单元测试程序中测试用例的编写,单元测试必定须要使用必定的测试框架,好比cxxtest、CppUnit、JUnit等等。固然,使用本身设计的测试框架也是一种选择。
 
再次,单元测试一般(我原本想写成“必定”,但又怕被指太绝对)须要经过获取代码覆盖报告这一形式以了解测试效果,来自开源社区的gcov和lcov相信被很多人所知。“代码覆盖”是一个不小的“×××”,乃至有的人会选择性地将其当作是“形式主义”。对于有这样反应的人,我相信是由于他们吃过了“代码覆盖”这“鸟”的苦头,由于那帮丫领导将百分百的代码覆盖率当成了考核目标,结果可想而知。
 
代码覆盖报告的真正做用,是帮助程序员了解被测代码的哪些“角落”没有“扫过”,从而指导测试用例的编写。若是一味地以百分百的代码覆盖率做为目标,这会让程序员承担巨大的工做压力。Parasoft(C++ Test工具的开发商)的一份研究报告中指出,覆盖率超过大约80%时,团队所承担的工做压力就很重了,这一报告可做为制定具体覆盖率的参考。
 
另外,即便以百分百的代码覆盖率为实施目标,很遗憾,仍是达不到彻底保证代码质量的目的,由于测试用例是能够“伪造”的。在软件行业,不论有多么好的软件开发方法,都依赖于程序员的专业精神,不然其效果将大打折扣,这一点对于单元测试也不例外。与其追求百分百的覆盖率,强调测试用例的质量更具意义(OMG,如何保证测试用例的质量?)。还有,千万不要将单元测试看成是“银弹”。
 
抱有“我天天都在作单元测试”幻想的程序员在幻想破灭之后,又会产生另外一种错觉 —— “单元测试是测试人员的事”。我得对这类程序员说:“你不负责任”。程序员编写程序后验证其中没有任何缺陷是理所固然的事。什么?你没有遗留缺陷?怎么证实?单元测试!
 
当幻觉与错觉都远离咱们之后,或许有的同仁会想:“单元测试就是一种测试!管它什么测试,目的都是为了保证软件质量的,那么在乎其具体含义干嘛呢?”不,精确掌握各词的具体含义是为了咱们能更高效地沟通!想想,咱们还有集成测试、系统测试,为何要造出这些新词?
 
后注:做者正在准备《软件企业成功实施单元测试的关健因素研究》这一论文,现需进行问卷调查。我写文章给您看,您参与个人问卷调查,算是礼尚往来,如何?问卷位于:
http://www.sojump.com/jq/1423894.aspx 。万分感谢您的参与!