单元测试给软件开发加速

发布日期:
2016-10-07

浏览次数:

我曾经咨询辅导过的一家企业,研发仪表产品,其嵌入式软件不是很复杂,因此, 采用的CPU档次不高,软件的编译环境不具备调试功能,每次代码写好、编译、烧片后才能验证软件功能。通常,编好的软件会埋藏一些bug,由于只能烧片后才能发现这些bug,而且编译环境又没有调试功能,工程师只好凭着猜测尝试修改缺陷,然后再烧片把软件下到设备中验证来bug的修复情况,据估计有时他们一天要烧片三十多次,花掉了大量的时间。

最近,汉捷又遇到了一家产值近百亿的高科技企业,他们的产品开发出现了软、硬件相互等待的现象,即软件需要硬件电路板先做好,让软件可以上板调试,而硬件又要求软件先做好,才可以对硬件电路板进行硬件功能测试。这样相互依恋的关系,导致彼此等待、相互冲突扯皮,最后项目延期。

上面两个案例,估计很多企业都遇到类似的情况,有没有什么方法可以解决呢?有,软件单元测试。

在国内,鲜有企业的软件开发人员做单元测试,不会做,更不想做。不想做的理由是:项目的进度这么紧张,哪里有时间做单元测试啊,或者,要做单元测试岂不是还要多招一些软件工程师,不划算!

真的是这样吗?十多年前,我在华为北研所带领一个团队负责一款产品的软件开发工作,我本人也承担了其实一部分底层驱动的开发工作。我们这个项目当时是北研所首批的IPD-CMM流程试点项目,从需求到设计再到编码都是有条不紊地进行着,各个模块的代码编写完成后,不仅要经过严格的代码review,之后还要做单元测试。以底层驱动模块为例,软件和硬件有接口,最直接的接口就是两个读写硬件寄存器的函数。驱动的单元测试,指的是在既不上硬件、也不跑上层应用的环境下,对驱动软件模块进行的独立测试。我们在PC机的VC++集成开发环境下做驱动代码的单元测试,把这两个寄存器读写函数置换为桩(stub)函数(也就是形式上相同的假函数),并通过开一块内存区或一个全局变量数组来模拟寄存器。通过VC++可视化编程的便利性生成图形界面,非常方便地执行各项功能操作和查看单元测试结果。经过了单元测试,非常便捷地发现了许多软件自身的bug,之后再和硬件进行集成测试,暴漏的更多的是软硬件接口问题和硬件自身问题,大大缩短集成的周期,因为一是缺陷少,二是缺陷定位容易,减少了软硬件沟通成本。单元测试虽然要花费一定的时间,然而它却成倍地缩减了系统测试时间。该项目到系统测试阶段,测试工程师测了不到一周时间,就很难能发现问题了,而以往没有做过单元测试的项目,测上一个月都不放心。

从那个项目结束后,我开始爱上了软件单元测试,特别是有与硬件有接口的驱动软件,哪怕硬件电路板准备好,我也要求软件工程师必须在方便快捷的PC机环境下先做好单元测试。在当时的华为北研所,越来越多的软件工程师也渐渐由开始的抵触造单元测试,到后来接受认可,因为有大量实际项目数据和案例证明,做单元测试不是延迟了项目进度,而是缩短了项目进度,同时也提升了产品质量。如,我们从实际项目统计数据来看,经过单元测试发现和解决一个缺陷所需要的工作量是单位1,则经过系统测试发现和解决一个缺陷需要的工作量是单位6。为什么单元测试会超人意料地高效呢?仅从一个方面来看好了,做过软件的都知道,有时系统测试发现的问题,开发人员可能一个月还无法定位,而单元测试测的是各个函数,基本不存在定位问题,自然不存在耗费在定位缺陷的时间了。

如今软件单元测试在华为早已成为一种如洗脸刷牙般的习惯。然而,我从事咨询工作六年来,去过四十多家企业,很少能看到有哪家企业做且有效地做软件单元测试,实为遗憾!不必说刚毕业的学生们,就是从业多年的软件开发管理者也对单元测试存在着严重的误解。如果能把单元测试有效做起来,案例中,做仪表的软件工程师就不必每次写完代码,浪费大量时间去烧片测试,完全可以在PC机上把逻辑处理、计算等与硬件不相关的软件实现进行充分地验证。软件开发人员写完驱动代码后,不必等待硬件电路板到位才让你的代码跑起来,通过单元测试的打桩方式,把软件和硬件先剥离开,同样可以让代码运行起来,而且更便捷,硬件很难发生的情况,在这样的模拟环境却很容易构造出了,因此,也就解决了软、硬件互等的锁死现象。

汉捷曾辅导软件单元测试的一家台湾企业,老总曾在美国TI工作,做IC出身,深知单元测试的重要性,他说:“IC每次流片就要花掉几百万、上千万美金,因此IC工程师在流片前不得不做详尽的单元测试,而做软件的好像不必付如此大的代价,因而就不做单元测试了,理由是项目很紧张,可是大家却有时间不断地事后返工!”

我想,如果我们的企业老总、研发总监对于软件单元测试认知程度如这家台湾企业老总那般深刻,那么软件单元测试就不会仅仅作为理论停留在软件工程教科书上,它会鲜活地走进项目里,成为一种实实在在的让项目进度加速的给力的实践活动!

相关推荐