(国电南瑞科技股份有限公司江苏省南京市210061)
摘要:本文研究了一种嵌入式软件自动化单元测试技术,提出了面向嵌入式软件的单元测试框架CppUTest,结合Jenkins(用Java编写的一种开源的持续集成工具),以ARP嵌入式软件平台为例,设计适用于ARP嵌入式软件平台开发的自动化单元测试技术,并验证在项目研发过程中应用的实际效果。
关键词:ARP嵌入式软件平台;自动化单元测试;CppUTest;Jenkins;
Abstract:Inthispaper,anautomatedunittestingtechnologyofembeddedsoftwarewasstudied.ItproposedakindofunittestingframeworkcalledCppUTestforembeddedsoftware.ItcombinedJenkins(anopensourcecontinuousintegrationtoolwritteninJava)andusedARPembeddedsoftwareplatformasanexample,designedakindofautomatedunittestingtechniquesforARPembeddedsoftwaredevelopmentplatform,andverifiedtheactualeffectinapplicationsoftheprojectdevelopmentprocess.
Keywords:ARPembeddedsoftwareplatform;automatedunittesting;CppUTest;Jenkins;
引言
嵌入式软件的单元测试是嵌入式软件质量控制的重要技术手段之一,是软件研发过程中不可或缺的环节[1]。单元测试在软件开发的前期就已经介入,它是软件测试的基础。如果做好了单元测试,后期的集成测试和系统测试就很顺利,因此会节约很多时间和成本。另外,在单元测试过程中,往往能发现一些深层次的问题,有些问题在集成测试和系统测试时很难发现。所以单元测试是构筑产品质量的基石。
由于嵌入式软件具有较高的复杂程度,传统的手工开发方式已经远远不能满足系统测试工作的要求和发展,这就使得自动化测试应运而生。自动化测试的出现改革了传统的手工模式,使得测试工作进入自动化的高速发展时代。项目的测试工作是一项工作量及其繁重的任务,手工测试不仅劳动密集程度过大,错误率也很高。而自动化测试的出现,弥补了这些缺陷,其优势是显而易见的,能够提高测试的准确率,从而极大地提高测试的效率。
新一代智能变电站建设以“系统高度集成、结构布局合理、技术装备先进、经济节能环保,支持调控一体”为特征,通过电网运行数据的全面采集和实时共享,支撑电网实时控制和智能调节,提升电网运行稳定性和可靠性。因此,顺应智能电网和智能变电站的发展和建设需求,在目前公司ARP系列产品的基础上,开发高质量的变电站设备,对于后续抢先占领市场,非常关键。这些设备有硬件和运行在设备上的嵌入式软件组成,因此,不仅要提高硬件的质量,也要提高嵌入式软件的质量。
为了满足嵌入式软件提高质量的需求,文中设计了一种适用于嵌入式软件的自动化单元测试技术,它不仅可以提高测试效率,而且使测试更充分、更精细,为嵌入式软件的质量保障提供更好的支撑。
1自动化单元测试框架设计
1.1自动化单元测试概述
从软件开发领域,单元测试并不是一个新概念。从早期使用Smalltalk编程语言的20世纪70年代开始,单元测试就已经出现,并一次又一次被证明是开发人员提高代码质量,加深理解类或方法功能需求的最佳手段之一[2]。
单元测试(unittesting),是指对软件中的最小可测试单元进行检查和验证[3]。单元测试是开发者编写的一小段代码,用于检验被测代码的一个很小的、很明确的功能是否正确。通常而言,一个单元测试是用于判断某个特定条件(或者场景)下某个特定函数的行为。
自动化单元测试是借助于测试工具和测试规范,局部或全部代替人工进行单元测试及提高测试效率的过程。对于测试工具的选择,需要评估究竟该选择哪种工具才能获得最佳测试结果。在软件测试过程中,并不是所有的测试工作都适合采用自动化的方式。由于单元测试用于检测代码的内部结构,因此单元测试的自动化将有效地提高软件开发的效率和软件的质量。
1.2自动化单元测试框架
在ARP嵌入式软件平台开发过程中,项目采用CppUTest作为白盒测试框架,编写自动化单元测试用例,并集成到Jenkins上进行编译和运行,并生成自动化测试报告和覆盖率报告。
CppUTest是一个功能全面的测试框架,是为了支持在多种操作系统上开发嵌入式软件而特别设计的程序[4]。它提供了基于JUnit的Jenkins的插件,能很好地集成到Jenkin集成服务器。它利用宏和断语为特定的测试用例定义了一个可执行的测试。它接受用户指定的测试用例名(一般取被测对象名)和测试名作为参数,并给出了一个作用域供填充测试宏语句和普通的C++代码。一系列测试的集合就构成一个简单的测试程序。同时它还提供对测试集合的配置,已满足不同规模测试的要求。
以往的单元测试,主要是借助测试工具,可以根据设计好的测试用例生成驱动函数,对被测函数进行打桩,插入被测程序,然后编译执行,并收集结果数据进行分析。文中以ARP嵌入式软件平台为例,提出的自动化单元测试与以往不同,它的关键在于自动化,无需太多的人工干预,有利于减少重复过程以节省时间、费用和工作量。自动化单元测试是通过在持续集成工具Jenkins上配置脚本命令,持续构建包括:源码版本自动更新、自动编译与运行、测试结果自动分析与报告生成、以及单元测试的覆盖率分析等任务,实现单元测试的高度自动化[5]。嵌入式软件自动化单元测试总体框架如图1所示:
图1自动化单元测试总体框架
2自动化单元测试项目实践
2.1自动化单元测试环境搭建
在ARP嵌入式软件平台自动化单元测试中,目标机的操作系统是Ubuntu,编译环境是与操作系统版本对应的GCC和G++。利用目标机编译和运行ARP嵌入式软件平台的源程序模块和单元测试程序模块,安装单元测试框架CppUTest,同时安装tomcat和Jenkins,用来部署自动化单元测试的持续构建。从UCMClearcase版本服务器上更新最新的源码到目标机上,选择被测程序模块,对问题函数编写单元测试用例,并对被测程序进行插桩,在目标机上完成编译、链接并运行,运行结果通过Jenkins上的JUnit插件,解析成测试报告,从而得到测试结论。
图2-1源码版本库自动更新
2.2源码版本库自动更新
为了使自动化单元测试需对嵌入式软件源码实时进行测试,为保证目标机源码实时更新,配置源码版本库自动更新功能。在Jenkins上构建源码代码版本库管理任务,实时监测版本变化功能,一旦发现版本变化,便触发版本管理工具更新源码,并记录下版本变化情况。如图2-1、2-2所示:
图2-2源码版本变化监测
2.3单元测试的代码结构设计
考虑到单元测试过程中,需要对源码进行打桩,因此在代码结构上将测试代码与源码隔开,测试代码目录为源码子目录,这样既不影响源码结构和编译,也能更方便地对源码进行用例测试。代码结构如图3所示:
图3自动化单元测试代码结构设计
2.4单元测试用例设计
以具体的单元测试用例为例,对问题函数initModbusDesc进行分析,发现其存在内存溢出的错误,在CppUTest单元测试框架下,设计Testcase,如图4所示。
图4单元测试用例举例
通过设计测试用例,测试条件覆盖,发现如果1032行if(dp->modbus_send_no_table!=NULL)为false,即dp->modbus_send_no_table==NULL,以及1083行if(dp->modbus_write_no_table!=NULL)同时为false时,即dp->modbus_write_no_table==NULL,此时1134行dp->send_min_addr[dp->send_min_no++]=(INT32)atol(dp->modbus_send_no_desc[0]);中的dp->modbus_send_no_desc[0]的数组是未初始化的,因此用dp->modbus_send_no_desc[0]进行赋值是会溢出的。
执行此异常用例本身是会导致单元测试程序core的,为了保证其他用例的顺利执行,因此选择Testcase的类型为IGNORE_TEST,单元测试框架识别该用例类型后的处理方式是忽略执行。
2.5单元测试自动编译及运行
通过命令行在Jenkins配置单元测试程序的自动化编译和自动执行,并对执行结果以报告形式展示。自动编译和执行配置如图5-1所示,单元测试执行结果和报告如图5-2所示,单元测试执行结果趋势如5-3所示。
2.6覆盖率设计
覆盖率是测量测试完整性的一个手段,是衡量测试是否完整的一个标准,我们编写的代码当中每个分支都应该是被覆盖的,这样才能保证测试是完全的,正确的.
覆盖率测试报告是评测测试是否完整的一个重要手段,测试覆盖率低下证明测试覆盖不足,当系统进行迭代开发的时候,就会出现各种各样的问题,而且覆盖率也是QA关注的一项重要指标,QA通过该报告和指标和开发者进行沟通,从而解决开发当中遗留的问题[6]。
在单元测试用例设计中,通过被测函数的单元测试语句覆盖、分支覆盖和条件覆盖的信息分析,来验证单元测试的有效性。在单元测试程序的makefile中,添加覆盖率编译参数“-fprofile-arcs-ftest-coverage”和链接参数“-lgcov-coverage”,单元测试编译之后,生成覆盖率中间文件.gcno,执行单元测试程序之后,生成覆盖率信息文件.gcda。然后,通过Gcovr工具,来收集单元测试用例运行后的覆盖率信息,以xml的形式保存覆盖率报告,然后由持续集成平台上的Cobertura插件将xml形式的覆盖率报告解析,并在网页上展示。
3结束语
嵌入式软件自动化单元测试是一个在实践中不断发展和完善的过程,对于一个团队而言,引入自动化单元测试对于提高开发效率和规范开发过程具有明显成效。另外,自动化单元测试是以持续集成平台为基础,从源码版本库自动更新、自动编译及运行、运行结果分析和覆盖率分析,逐步完善、提高,最终实现整体的自动化。嵌入式软件自动化单元测试在ARP嵌入式软件平台的应用,实际解决了嵌入式代码存在的问题,能够更有效地从整体上管理和提高产品的质量,为ARP嵌入式软件平台的研发提供了有益的参考。
参考文献
[1]胡丹,杜新华.基于目标机的嵌入式软件单元测试电子测量技术,2006,29(2):33-35.
[2]张巍,尹海波,孙立财.软件的单元测试方法.光电技术应
用》,2006,21(2):36-38.
[3]姚渝.嵌入式软件单元测试自动化的研究与实现.东南大学,2007.
[4]卫征.嵌入式软件测试自动化技术研究.北京工业大学,2009.
[5]陈刚,羌铃铃.软件项目开发中的持续集成研究[J].项目管理技术,2011(12):103.
[6]高智杰,雷红瑛,史国华.基于覆盖率的嵌入式软件单元测试研究.全国嵌入式系统与单片机学术交流会,2007.
作者简介
屠小兵(1974—),男,硕士,工程师,主要研究方向:电网调度自动化技术。E-mail:tuxiaobing@sgepri.sgcc.com.cn
陆继翔(1973—),男,硕士,主要研究方向:软件工程。E-mail:lujixiang@sgepri.sgcc.com.cn
刘杰(1986—),男,学士,工程师,主要研究方向:电网调度自动化技术。E-mail:liu-jie@sgepri.sgcc.com.cn