Linux下SANE Driver自动化测试工具的设计与实现
扫描二维码
随时随地手机看文章
SANE(Scanner Access Now Easy)是一个应用程序接口API(Application Programming Interface)[1],提供了对光栅图像扫描硬件的标准访问[2]。Linux对扫描仪的支持就是通过SANE实现的。SANE标准中将实现SANE接口的驱动程序称为SANE Driver或者SANE后端程序;将调用SANE接口的应用程序称为SANE前端程序;将对扫描设备的各种控制抽象为SANE选项,resolution就是其中一个SANE选项。
对扫描仪驱动程序进行测试主要包括功能测试和性能测试。功能测试主要指扫描质量、图像质量是否满足用户需求;性能测试主要指扫描效率,也就是扫描一幅图像所需的时间。严格地说,由于SANE前端程序与SANE后端程序均遵守SANE标准,任何一个SANE前端程序都可以用来测试SANE后端程序。但由于目前Linux下没有专门的SANE Driver测试工具,通常测试人员将扫描应用程序用于测试SANE Driver,而在Linux下常用XSANE作为测试工具。XSANE应用程序是基于GTK的sane图像处理软件,它可通过扫描仪和照相机等设备获得图像。
XSANE功能比较强大,但是由于其主要面向用户应用,作为测试工具则存在一些不足:(1)功能测试时效率低下,如果所要测试的选项数目比较多时,测试的工作量很大而且容易出错,而其所支持的批次扫描生成脚本很复杂,而且脚本很难维护;(2)性能测试时不能自动计算扫描时间,手工计算工作量大且误差也较大。此外,还存在一些其他问题:如不能显示选项的详细信息、不能动态更新可用的扫描设备以及不能选择其他可用设备等。
针对以上问题,本文通过引用脚本技术[3],采用一种高效的遍历算法工具,有效地解决了上述问题。该工具能够适用所有采用SANE标准的驱动程序,且能够自动遍历所有的选项及其取值。用户只需根据测试需要写好测试脚本,该工具就可以根据脚本进行多次扫描。因此可以较大程度地减少SANE Driver测试所需的人员及其时间。
1 整体架构设计
针对XSANE用作测试工具存在的问题以及测试需求,通过如下设计能得到有效解决。将工具分成5个功能模块:更新设备、列出选项、手动扫描、脚本扫描以及产生脚本。
(1)更新设备:支持用户随时更新设备列表。
(2)列出选项:可以列出SANE后端所定义的所有选项,且只显示当前设备所支持选项的相关信息,还可以根据用户的选择相应地显示SANE后端的版本号及一些设置冲突的警告信息。
(3)手动扫描:类似一般的前端程序,主要实现单次扫描,只显示当前设备所支持的选项及其取值。
(4)脚本扫描:是自动化测试的关键。能够读入一个脚本文件,然后对脚本中各选项的组合值进行遍历,每取到一个组合,便扫描一次。
(5)产生脚本:可以将当前设备所支持的选项及其取值范围记录在脚本文档中。该脚本相当于一个脚本模板,以后的脚本可以只在此基础上稍作修改即可。
2 工具的实现
基于以上架构设计在Linux系统下用GTK+和C语言来实现整个工具。
2.1 更新设备
在用户扫描过程中,可能会有新的扫描设备打开,也可能现有的扫描设备关闭,因此,有必要让用户随时知道可用的设备列表。其设计思路是:在选择更新设备后,调用sane_get_devices来获得可用的设备列表。实现时,为了允许用户在更新设备时进行其他操作,可将更新的操作放至一个新的线程中去实现。当可用设备为0时,应给用户相应的提示。
2.2 列出选项
根据测试需要,这里要求给出SANE后端的版本号,可用选项的详细信息以及警告信息。关于版本号,SANE标准中给出了5个宏,该工具主要直接调用后面的3个宏:即SANE_VERSION_MAJOR、SANE_VERSION_MINOR、SANE_VERSION_BUILD,分别获得SANE后端最大、最小以及编译版本号。
对于选项的详细信息,SANE标准中有一个专门用来描述的结构即SANE_Option_ Descriptor。调用SANE标准中的sane_get_option_descriptor后便会返回这个结构体,记录这个选项的详细信息。
警告信息主要通过分析结构体SANE_Option_ Descriptor中的cap值。由SANE标准可知,当SANE_CAP_ SOFT_SELECT被设置时,SANE_CAP_SOFT_DETECT也会被设置,故cap值不能为5;SANE_CAP_SOFT_SELECT和SANE_CAP_HARD_SELECT不能同时被设置,故cap值不能为3。当某一个选项的cap值不为3或5时,可认为这个选项设置是正确的。
实现时,可以将版本信息、选项信息及警告信息分别写至三个文件中,然后根据用户的操作读入相应的文件。
2.3 手动扫描
一次完整的扫描过程包括两个部分:配置设备和获取图像。配置设备主要通过sane_control_option来完成。sane_control_option可以用于获取选项的当前参数,也可以用于设置选项的参数。设置完参数后,先调用sane_start,然后一直调用sane_read读图像数据直至sane_read返回状态为SANE_STATUS_EOF,最后不管读图像是否成功均要调用sane_cancel。
实现时,当用户选择手动扫描后会创建一个新的线程去执行,配置设备和获取图像均包含在新的线程中。每进行一次用户扫描,都会新建一个线程。同时为了方便测试人员,工具在手动扫描和后面的脚本扫描中均会记录一些重要信息:如图像的原始大小及实际获得的大小、 sane_start和sane_read的时间、一些操作的返回信息及图片保存目录和名字等。
2.4 脚本扫描
脚本扫描与手动扫描是相互独立的。用户可以只选择手动扫描,也可以只选择脚本扫描。不过,它们之间有着紧密的联系,其扫描流程都是一样的。手动扫描与脚本扫描的结构体系如图1所示。脚本扫描可以看作是多次的手动扫描,所不同的是,手动扫描是从界面获得选项值,而脚本扫描是从文本获得选项值。
脚本扫描的流程是:首先检查脚本的语法正确性,然后分析脚本,遍历各个选项值的组合,每得到一个组合,便扫描一次,当扫描完成时,再取下一组合扫描直至遍历完所有的组合。
实现时,每扫描一次,均创建一个新线程,下一次扫描要等上一线程结束后才开始。
2.5 产生脚本
产生的脚本主要列出设备所支持的选项名字及其取值范围,然后以特定的格式写入脚本中[4]。由于结构体SANE_Option_Descriptor中包括选项的各种信息,因此结构体中的元素title可作为该选项的名字,而选项取值范围可从结构体中的联合体constraint得到。实现时,应允许用户选择保存路径。
2.6 遍历算法研究
在对SANE Driver测试时,一般会选中一些选项进行全组合或部分组合进行测试。以两个选项为例:mode值为 Color和Gray,resolution值为75和100,测试时就用Color 75、Color 100, Gray 75、 Gray 100四种组合扫描4次。xsane中的批次扫描采用了类似的方法,它将所要扫描的每种组合记录在文本中,然后通过读文本进行扫描。当扫描次数较多时,文本就非常冗长而且很难维护。
测试工具中采用的脚本使用了键值对的形式:
mode=Color,Gray,Binary
resolution=75,100,150,200,300,400,500,600,1 200,2 400,4 800,9 600,19 200
对于上面的脚本,通常会采用直接循环法:用下面一个结构体:
struct option {
char names[15];
char values[10][20];
} options[MAXOPTIONSNUMBER];
来存储每一种组合,用一个数组size保存各个选项值的个数。比如上例中,第一个选项mode有3个值,故size[0]=3;然后用一个数组index来存储选项的当前值,如mode第一个值为Color,则可表示为index[0]=Color。假如只有mode和resolution两个选项,那么只需2个for循环即可遍历选项的取值。其代码如下:
for(index[0]=0;index[0]<size[0];index[0]++)
for(index[1]=0;index[1]<size[1];index[1]++)
{
for(int i=0;i<2;i++)
pass_option_setting_to_dev
(options[i].names,options[i].values[indexs[i]] );
// pass_option_setting_to_dev为传递参数给设备的函数
...
}
本文介绍的算法思路简单,容易理解。针对上例中的两个选项,采用上述的方法可以很好地解决问题。但是上述的算法中有多少个选项就有多少个for循环,而且该方法只适用于选项个数一定的情况下。因为当选项个数有变动时,都要增加或删除相应的for循环数。而现实中的脚本其选项的个数是不定的,因此上述的算法可扩展性较差,不适合用于脚本扫描。但只要对上述算法稍作修改即可成为一种简单高效的遍历算法[5]。该算法的脚本仍采用键值对这种简洁的脚本格式,并且可以很好地适应选项个数或者选项值个数的变化。假设变量OPT_NUM代表选项的个数,其代码如下:
while(1){
for( int i=0;i<OPT_NUM;i++){
pass_option_setting_to_dev
(options[i].names,options[i].values[indexs[i]] );
...
}
int k= OPT_NUM-1;
while(1){
if(index[k]<size[k]-1) {
index[k]++;break;
}
else{
index[k]=0; k--;
}
}
if(k<0)
break;
}
3 测试工具对比
XSANE与自动化测试工具对比如表1所示。
本文以SANE标准为基础,针对xsane存在的不足,结合测试需求,实现了SANE Driver自动化测试工具。实际应用结果表明,与原有的测试工具相比,大大提高了测试效率,极大地减少了测试人员的工作量。
参考文献
[1] SANE home page[DB/OL].http://www.sane-project.org, 2001.
[2] 张安清.基于SANE标准的光栅扫描设备应用程序的开发[J].小型微型计算机系统,2001,22(10):1216-1218.
[3] 凌永发,张云生,郭秀萍.软件自动化测试中的脚本技术[J].云南民族学院学报(自然科学版),2002,11(1):544-548.
[4] 蒋云,赵佳宝.自动化测试脚本自动生成技术的研究[J].计算机技术与发展,2007,17(7):4-7.
[5] 《编程之美》小组.编程之美:微软技术面试心得[M].北京:电子工业出版社,2008.