马雪怀
摘要:在日益广泛应用的嵌入式系统中,软件测试因为系统平台局限性需要重复下装,耗费较大的测试资源与时间成本。文章根据嵌入式系统软件的特性,结合实际案例智能楼宇对讲系统DH-T90,从测试环境描述、测试用例筛选、回归策略选择等一系列方法步骤,较系统的说明一种制定智能楼宇对讲系统接口测试的规划策略,从而优化嵌入式系统的接口测试,规范了测试风险,并提升了测试效率。
关键词:软件工程;嵌入式;测试方法;测试用例;回归测试
中图分类号:TP311 文献标识码:A 文章编号:1009-3044(2015)09-0065-04
Abstract: In these days, embedded system is widely used in our life.Software testing needs a high test resources and time consuming.It needs to be repeated loading because of limitations of system platform. According to the characteristics of embedded system software, combined with the actual case of intelligent building intercom system DH-T90. There is a series of method description, includes test environment, test cases and regression strategy.It systematically provides a set of test planning strategy to intelligent building intercom system interface.So as to optimize the test interface of the embedded system, standardize the testing risk, and improve test efficiency。
Key words: software engineering,embedded; test method; test cases; regression test
随着手机、平板电脑等便携电子设备的广泛应用,集成化的嵌入式系统已经成为智慧城市的重要应用。作为系统的开发者,应该如何对嵌入式软件系统中模块进行接口测试?显然,如果原封不动的套用我们很熟悉的通用平台上应用软件的集成测试方法,在一些关键环节无法实现对嵌入式软件的接口测试。文章根据嵌入式系统软件的特性,结合实际案例智能楼宇对讲系统DH-T90,从测试环境、测试模型、测试用例等方面描述如何制定智能楼宇对讲系统的接口测试策略。
1 嵌入式软件测试环境
软件工程意义上的软件测试环境是指为了完成软件测试工作所必需的硬件、软件、外设、历史数据的总称。一般说来,良好的测试环境需要具备三大要素:优化的测试模型、多样化的系统配置以及熟练使用工具的测试员。
在规划测试策略与计划时,测试环境的建设是测试实施的一个重要阶段,测试环境的适合与否会严重影响测试结果的真实性与准确性。在智能楼宇对讲系统中,由于软件是烧写在硬件芯片方案中直接执行的(就是所谓“嵌入式”),所以最可靠的测试环境,就是将待测软件烧录后再执行测试,但是这种模式下,有多少次回归就要进行多少次烧录芯片的操作,无疑增大了测试资源的投入,也限制了软件系统的快速迭代。目前业界比较通行的方式是采用虚拟机(或者模拟器)的方式,在可接受的拟真度情况下,应用虚拟机对嵌入式软件进行模拟烧录、回归测试并最后下装验证。在DH-T90智能楼宇对讲系统中,应用软件以APP文件烧录在芯片中,因此,我们在模拟测试环境下执行功能模块的接口测试。
2 嵌入式系统的软件架构与模块
一般的,在进行软件模块接口测试中,首先需要了解软件总体架构与模块划分的逻辑关系,理解并掌握模块间的接口定义,在此基础上才能构建测试模型与设计测试方法。
2.1 DH-T90的软件架构
从概要设计书中,我们了解了DH-T90的软件总体架构:
1)表现层(ui):主要是用户界面这一块。
2)业务逻辑层(logic):具体的业务逻辑这块,和问题领域相关。
3)系统平台层(system):内核、各种驱动、c库等等。
并且在架构中制定了模块依赖规则:同层次的模块相互依赖,不允许下层模块依赖与上层模块。
2.2软件模块间的依赖性
了解了软件的总体架构后,需要根据测试需求明确DH-T90的测试范围我们限定于APP子系统中,而我们的接口测试对象就聚焦于“UI”、“Logic”层所包含的各模块间接口。
接下来就需要充分理解并掌握“UI”、“Logic”层所包含各模块的依赖关系。通过图1的方式,可以对模块划分类别,并清晰的勾勒出测试模块间的依赖关系:
1)实体类、Widget:是完成一个模块的基本单位,和别的模块基本是不相关的,独立性高;
2)控制类、表现层:主要是其协调、控制控制这些基本组件的功能,和很多的模块相互关联;
3)其中的单向箭头说明的模块依赖关系。
图1 UI、Logic的模块依赖
根据模块分类及相互间的依赖关系,我们需要对测试范围内的模块进行梳理。表1列举了DH-T90系统中部分模块间的相互依赖关系。
表1 模块依赖关系列表
[模块编号\&模块名称\&模块类别\&模块功能\&依赖于模块\&C001\&CM_keyboard\&控制类\&物理按键输入响应\&Logic层Common\&C002\&CM_touchpanel\&控制类\&触摸屏输入响应\&Logic层Common\&C003\&CM_orange\&控制类\&多图层操作\&Logic层Common\&C004\&CM_cedar\&控制类\&视频解码,视频播放\&Logic层Common\&C005\&CM_audio\&控制类\&音频解码\&Logic层Common\&C006\&CM_FTK\&控制类\&ui框架\&Logic层Common\&U001\&UI_Config\&表现层\&工程设置界面\&C001、C002、C006\&U002\&UI_AddrSetting\&表现层\&网络地址设置界面\&C001、C002、C006、U001\&U003\&UI_PwdSetting\&表现层\&密码设置界面\&C001、C002、C006、U001\&U004\&UI_VolSetting\&表现层\&音量设置界面\&C001、C005、C006、U001\&U005\&UI_VideoAdujst\&表现层\&视频角度设置界面\&C001、C003、C004、U001\&]
2.3软件模块间的接口定义
按照表1中模块依赖关系,我们能够较明确的了解到被依赖较多的模块有哪些,比如:CM_keyboard、CM_FTK、UI_Config等。针对这些模块,我们需要掌握模块接口参数说明,因为在后续制定测试模型时,模块依赖关系的强弱将作为计算测试优先级的因素。
从软件概要设计中明确CM_keyboard、CM_FTK、UI_Config的模块接口参数如下:
typedef struct
{
char compile_date[20]; /* 软件编译时间. */
char compile_time[20];
int key_enable; /* 控制mainwin消息中的按键处理,按键是否禁用,呼叫,响玲,通话过程中,禁用按键跳转到其它界面(安防,中心,呼叫,监视). */
int key_enable_call; /* 控制mainwin消息中的按键处理时是否处理 DVP_VKEY_CALL 消息. */
int status_enable; /*状态栏按钮是否被禁用*/
int becall_enable; /*被叫是否禁用,正在报警和布防延时过程中,进入来电呼入 */
int cur_rec; /*正在录音*/
int server_time; /*登录后,获取的服务器时间*/
int city; /*天气城市*/
int weather; /*天气状况,(0-6)*/
int temperature; /*温度,weather>0时显示温度*/
int msg_sync_time; /*最新消息时间*/
int is_register;
int is_login; /*登录标识*/
int server_sync_time; /* 设备与服务器状态同步时间 */
int sync_server_time_enable; /*是否同步服务器时间*/
Z_SLIST dev2ip_list; /*设备编号与IP对应表(DEV2IP_ITEM)*/
Z_SLIST auth_lock_list; /*授权限制码*/
Z_SLIST auth_unlock_list; /*授权解锁码*/
int user_change_addr; /*用户修改了地址(IP或房号)*/
char photo_dir[100]; /*图片目录. SD卡或udisk目录*/
char udp_key_data[1024]; /*udp数据加密key,最大1K*/
int udp_key_len; /*upd数据加密key,输入字符长度*/
int udp_key_enable; /*upd数据加密key有效状态 */
DVP_MOUDLE_STATE moudle; /*系统模块状态*/
int off_call_moudle; /*是否关闭电话模块*/
int off_screen_save; /*是否关闭屏保,进入工程设置需要关闭屏保*/
int off_alarm_moudle; /*是否关闭报警,进入工程设置需要关闭屏保*/
int rec_usr_operation; /*录制用户操作*/
char test_server_ip[16]; /*测试服务器地址,如果没有设置则使用中心服务器地址*/
char alarm_recvlist[16 * 20]; /*ip,ip,... 20个,接收报警设备列表,目前为所有中心机(最多20个). 为什么不定义char alarm_recvlist[20][16];因为报警很少,在用它时再解析,可以减少cpu操作*/
int monitor_ret_state; /*梯口应答监视状态,室内机使用此变量*/
int lcdpanel_on; /*指示LCD是否开启,在X227出现黑屏界面被其它界面盖住后无法点亮及按开锁键无法点高问题*/
} DVP_SYS_STATE;
3 测试策略与测试方法
3.1建立接口测试策略
所谓测试策略就是对于一系列待测试模块,我们需要考虑该如何安排测试序列,优先测试哪些模块才能使投入的测试资源更高效。根据历史测试经验,一般定义的模块测试策略公式:优先级数值=模块依赖系数×模块功能系数。然后根据计算出的每个模块的优先级数值来安排测试序列。
根据表1中模块依赖关系,按照被依赖越多的模块,依赖系数越高的原则,制定每个模块的依赖系数。同时根据各模块实现功能重要性,列举模块功能系数。最后按照测试策略公式计算出的优先级系数值,如下表2。
表2 模块依赖系数、功能系数与优先级系数
[模块编号\&模块名称\&依赖于模块\&依赖系数\&模块功能\&功能系数\&优先级数值\&C001\&CM_keyboard\&Logic层Common\&5\&物理按键输入响应\&3\&15\&C002\&CM_touchpanel\&Logic层Common\&3\&触摸屏输入响应\&3\&9\&C003\&CM_orange\&Logic层Common\&1\&多图层操作\&2\&2\&C004\&CM_cedar\&Logic层Common\&1\&视频解码,视频播放\&3\&3\&C005\&CM_audio\&Logic层Common\&1\&音频解码\&3\&3\&C006\&CM_FTK\&Logic层Common\&4\&ui框架\&2\&8\&U001\&UI_Config\&C001、C002、C006\&4\&工程设置界面\&2\&8\&U002\&UI_AddrSetting\&C001、C002、C006、U001\&1\&网络地址设置界面\&2\&2\&U003\&UI_PwdSetting\&C001、C002、C006、U001\&1\&密码设置界面\&1\&1\&U004\&UI_VolSetting\&C001、C005、C006、U001\&1\&音量设置界面\&1\&1\&U005\&UI_VideoAdujst\&C001、C003、C004、U001\&1\&视频角度设置界面\&1\&1\&]
最后,根据模块优先级数值表(表2),在测试策略中明确出各模块测试序列。
3.2设计接口测试方法
3.2.1评估测试方法
确定模块优先级后,不是一个一个的顺序对模块接口进行测试,而是采用对两个或者三个模块进行组合测试的方法,组合策略的选择是一个比较严谨的评估过程。
不同组合,对于测试用例的要求不尽相同。基于标准组合定义为:CA=Nt,其中CA为组合用例数,N为模块接口输入用例范围(也就是所谓的组合模式中的“水平”),t为模块依赖系数(也就是所谓的组合模式中的“因子”)。因此如果按照完全覆盖标准组合测试来设计两两模块组合测试用例,将需要比较庞大的测试用例集。而对于实用楼宇对讲系统的模块测试经验数据库,我们可以选择变强度组合测试的方法来设计测试用例,以期达到在保持充分质量水平的情况下,减少测试用例覆盖,缩短测试周期,提高项目整体效率。
3.2.2设计高效的测试用例
所谓强度组合测试,指在完全覆盖的标准组合测试用例范围内,根据模块接口测试经验数据库进行一定程度的比对,在保证一定覆盖度比例与重点历史权限全关联的情况下,筛选出较少的必要测试用例集。一般的,我们在测试检验数据库比对中采用正交表模式,设计筛选公式自动完成测试用例集的生成。正交表应用与测试经验数据库的实例如表3。
表3 测试用例正交表
[用例编码\&经验数据库分类\&模块编号\&模块名称\&CA=Nt\&选取标志\&001\&SY001\&C001\&CM_keyboard\&CA=32=9
\&T\&002\&SY001\&C001\&CM_keyboard\&F\&003\&SY002\&C001\&CM_keyboard\&T\&...\&...\&...\&...\&...\&003\&SY002\&U001\&UI_Config\&CA=57=78125\&T\&004\&SY002\&U001\&UI_Config\&F\&005\&SY003\&U001\&UI_Config\&T\&006\&SY004\&U001\&UI_Config\&T\&007\&SY005\&U001\&UI_Config\&T\&...\&...\&...\&...\&...\&]
从以上表3看到,对于编号为“C006”与“U001”的模块间的测试用例由于其“依赖系数”较高,所以在测试经验库比对中有高比例的测试用例数进入用例集。
4 有效的迭代与回归策略
4.1有效桩的设计
由于嵌入式系统的模块集成受限于平台编译与下装,所以一般我们在进行模块间接口测试时,采用桩来替代已完整通过功能测试的(单元)模块。不同模块间的接口测试,需要考虑的因素有很多,根据测试策略,采用桩的目的就是进行自动化的性能测试,也就是采用自动化脚本,对耦合最紧密的接口参数进行输入输出封装,并验证软件长稳性能。
在本文的接口测试例子中,我们设计的桩用于替代应用频度最高(依赖系数最高)的模块C001:CM_keyboard,也就是设计S001:STUB_keyboard,对应于CM_keyboard封装的输入输出参数,例如:“int key_enable_call”等上文说明的编号C001模块中定义的参数,从而实现对应于相关联模块接口的桩测试。
有效桩的设计关系到整体接口测试效率与可靠的性能测试,自动化性能测试一般采用指令脚本的方式执行。
4.2 接口测试的迭代版本控制
在完成接口测试桩设计后,更进一步就要进行迭代版本的控制。因为接口测试中用桩替代功能模块进行接口参数验证是有较高代价的,在测试的任何一个阶段,如果待测接口关联的模块功能发生改变,那么意味着桩就需重新设计。所以模块内任何的改变情况下,继续用继承桩进行测试,就可能会遗漏对模块修改引发错误的发现。
制定迭代版本控制的原则,关键就是坚持在模块功能完整测试通过后,进行接口桩设计与自动化性能测试,而版本迭代就要求集中在性能测试阶段,迭代重点就应该是桩的接口参数封装是否完整以及自动化测试脚本更新,尽量减少功能模块的变更。
4.3 回归测试度量
在嵌入式系统中,从测试用例库抽取的用例集也可能变得相当大,如果每次回归测试都需要重新运行完整的测试流程,那么测试的时间与资源开销就很大。回归测试的价值在于它是一个能够检测到回归错误的受控实验。选择回归测试策略应该兼顾效率和有效性两个方面。当然“再测试全部用例”仍然是所有策略中安全性和覆盖性最高的一种。但由于嵌入式系统对于时间与资源等测试开销的限制,一般不允许选择“再测试全部用例”的回归测试策略。
在本文的接口测试案例中,我们选择三种方式相结合进行回归测试,包括:
1)基于风险选择测试
可以基于一定的风险标准来从基线测试用例集中选择部分用例用于回归测试。首先运行最重要的、关键的和可疑的测试,而跳过那些非关键的、优先级别低的或者高稳定的测试用例,这些用例即便可能测试到缺陷,这些缺陷的严重性也较低。一般而言,测试选择从主要特征到次要特征。
2)基于操作剖面选择测试
继承上文提到的针对性测试策略,用更精简测试用例的分布情况来反映系统的实际使用情况。回归测试所使用的测试用例个数可以由测试预算确定,即回归测试可以优先选择那些对最重要或最频繁使用功能模块的测试用例,释放和缓解最高级别的风险,有助于尽早发现那些对接口可靠性有最大影响的故障。
3)再测试修改的部分
当我们对修改后提交的模块代码有足够的信心时,就通过关联性分析模块修改情况与修改的影响,将回归测试局限于被改变的模块和它的接口上。通常,一个回归错误一定涉及一个新的、修改的或删除的代码农而不再扩散到接口相关联的模块。
5 结束语
对于嵌入式系统的接口测试策略,需要时间和人力来计划、实施和管理。在给定的进度下,尽可能实现有效率的模块关系模式计算和桩设计,需要对测试用例集进行优化筛选并且选择相应的回归测试方法。当一系列都成为规范时候,系统接口测试就能够保证足够的效率与可控的风险。
参考文献:
[1] Ian Sommerville. 软件工程(英文版)[M]. 9版. 北京: 机械工业出版社, 2011.
[2] 陈云川. 嵌入式软件调试技术[M]. 北京: 电子工业出版社, 2009.
[3] 刘利枚, 汪文勇, 唐科. 嵌入式软件测试方法与技术[J]. 计算机与现代化, 2005(4): 123-126.
[8] Dr Ingrid B.Ottevanger,贾国莹, 译. 基于风险的测试策略. 51测试天地[EB/OL].www.51testing.com.