本文主要研究数据驱动的测试脚本自动生成系统的设计方法。目标是能够完成一个测试脚本自动生成系统,该系统可以降低测试人员编写和修改测试脚本的难度,提供给测试人员在脚本编写中更便捷直观的界面,并且可以面向需要有大量且多种测试数据导入进行测试的系统(如银行系统),简化测试人员导入和获取数据的过程,提高性能测试的实施效率。
在本文中主要需要研究并完成的研究内容主要包括脚本构成和测试数据两个方面,主要分为以下四部分:
测试脚本获取与生成:在实际工作中,性能测试脚本可能由测试人员进行手动编写,也可能由测试人员录制后再进行修改。因此系统应该具备读取空白脚本文件或录制的脚本文件的能力。在测试人员配置完成后,也应该让测试人员获得修改后的测试脚本。在生成过程中,我们需要对测试对象在脚本中的相关参数进行配置,以获得可用的测试脚本。
测试脚本编辑:测试脚本编辑需要将脚本语句输出到脚本文件的指定位置,在本系统中由脚本语句模板库提供编辑脚本所需的脚本语句,根据用户的选择和配置将指定语句输出到脚本文件指定位置。在该部分研究中,除了常规语句的输出,主要还需要研究参数化语句的配置。在这部分中主要的研究内容是通过脚本语言中的关联函数从脚本手动的添加参数化字段,如何正确的获取参数化字段的头尾信息,生成正确的参数化关联函数是这部分的重点。
测试数据获取:测试数据是参数化操作完成的必要组成部分。在这部分中,需要研究如何生成更符合实际应用需求的数据。能够根据用户配置生成指定数量和类型的测试数据。尤其是对于复合型测试数据生成规则及方法的研究,是这部分的重点。
测试脚本验证:这部分主要包括两部分内容:一是对于数据的验证,主是要脚本自身需要的参数,如测试对象的配置相关参数和调用的脚本语句配置参数。另一部分是对于语句的验证,整个脚本语句的安排和配置是否符合可用脚本的标准,如何判断也是本系统的研究内容。
为了同时兼具商业测试软件的处理能力和自开发测试工具的高可定制性,在解决文中的提出的问题时,我们采用基于现有的商业性能测试软件再开发的模式,在商业软件的基础上,开发工具,提升脚本的定制与自动生成能力。首先我们分析性能测试的基础流程。
系统用例模型设计如下图3
图3
在本系统中用户主要操作由四部分组成:WEB设置,语句配置,数据配置和脚本配置。
测试对象配置:
测试对象配置主要包括测试对象的配置,在这部分中用户需要配置测试对象的相关信息。
语句配置:
语句配置主要包括对于需要添加的脚本语句的相关配置。包括语句设置,这部分主要负责用户选择需要添加的脚本语句,并对语句中需要输入的语句参数进行配置。参数化,这部分系统在对XML文件进行检索后,列出脚本文件中可进行参数化的部分,由用户确定需要进行参数化的部分并与相关的数据库字段进行关联。在这部分中用户还要确认添加的脚本语句的位置,以便将语句插入到脚本文件的正确位置。同时这部分也允许用户对脚本进行手动添加脚本语句。
数据配置:
数据配置主要包括系统对测试数据的相关操作,这部分主要包括数据库配置和数据生成配置两部分。数据库配置是由用户提供已经保存了测试数据的数据库,在这部分中需要确定数据库的保存路径,系统从中抽取指定的数据。在数据生成配置中,这部分则是在用户没有提供测试数据的前提下,生成随机测试数据。因此需要用户制订测试数据规则,生成符合规则的数据后导入对应的参数
脚本配置:
这部分提供的是脚本保存的位置,可以将完成后的测试脚本保存到指定的文件路径下。
系统性能测试流程如下图4:
图4
在本系统中主要分为四步解决本论文提出的三个问题:
1. 配置测试对象:主要提供的功能是对测试对象的URL,端口进行设置以及其他要在脚本初始化语句中写入的参数,确认性能测试脚本的运行对象。这一步也为后续脚本中需要调用的URL相关LR脚本语句提供参数。
2. 获取测试参数:在获取了测试对象以后,此功能提供需要进行测试的参数项,并对其实施参数化,以备下一步导入测试数据。在这一步中我们主要解决测试脚本中参数化自动获取的问题:
在这部分中,根据多次页面手工测试输入数据生成的XML,对其中的字段进行逐行逐列的比对,得到多次运行中发生变化的字段,并且根据标记规则(如字段中的标志位)标记其前后字段的位置。并将标记字段间的部分在参数化列表中列出来,由用户确认后,用LR脚本的参数化字段替换指定的字段,对指定部分进行参数化。
3. 生成测试数据:在获得了测试项以后,此功能生成测试项所需的测试数据。
这部分主要解决测试参数获取测试数据的问题:在这一步中为了解决该问题同样使用两种方法:一种是由用户提供的测试数据,这些测试数据可以以数据库或手动输入的方式存在,如果有,则将用户提供的测试数据与脚本中对应的字段相关联,使用用户提供的数据库中的数据作为测试数据。另一种方法则是由用户制订测试数据规则,在银行系统中的数据主要包括字母和数字,如数据共几位,是否包括数字,字母等生成规则。由系统根据测试数据规则自动生成随机的测试数据。
4. 生成测试脚本。在实际操作中,仅仅对参数进行参数化还是不够的,还需要对测试脚本的初始化和结束,检查点,集合点等测试脚本的相关测试项进行设置。这部分主要要解决论文中提出的脚本编辑的便捷化,提升其复用性的问题。
在这部分中我们将脚本语句模板文字化显示在显示上,用户设置所需要添加的脚本语句和脚本语句在文件中的位置,以及脚本语句的相关参数。设置完毕后,系统查询语句模板库,调用语句模板并将用户设置的参数填写到语句中去,形成完整的脚本语句添加到指定的位置。
在完成参数化及其测试数据导入,和脚本语句的添加后。就可以准备生成脚本,此时提供脚本预览,并允许用户对脚本进行手动修改。完成后即可进行保存。在生成文件前,系统自动对脚本中相关语句进行相关的规则验证,如果语句添加存在问题则返回错误信息。如果正确则在指定位置生成脚本文件。
测试中往往测试工具往往需要面向不同的测试对象,在生成的脚本中也需要添加测试对象的 URL和地址。因此需要用户提供测试对象有相关信息。用户进行配置后系统对用户输入进行合法性校验,校验通过进行保存。
图5
该模块如上图5所示,主要分为如下几步:
用户输入:提供设置界面,等待用户进行输入。
用户输入校验:对用户输入进行合法性校验,主要对测试对象页面的配置参数进行校验,检查其是否符合标准。如果不正确则返回错误信息,并返回等待用户输入的状态。
配置记录:如果通过校验则在数据库中记录的输入的参数,等待其他模块的调用。
在明确了测试对象后,系统需要确认被测对象有哪些字段是需要进行测试的参数,即获取测试参数。在本系统中主要针对的是由数据驱动的测试,脚本的重点也在于对于测试数据的定位和导入,这些数据在手工测试中需要测试人员手动输入。LoadRunner为了将这类操作简化提供了参数化的功能。同时,通过编写脚本也同样可以达到参数化的效果。该模块的主要功能就是确认有哪些字段是需要进行参数化的测试参数项,并对他们进行记录和保存,以便之后导入测试数据。
图6
该模块如上图6所示,主要分为如下几步:
获取测试对象:获得测试对象指定测试页面的脚本文件。
测试项查找:此功能需要用户配置测试项,或进行脚本比对以定位测试项,脚本比对需导入测试页面录制的脚本(同一页面至少两次录制),该功能通过对比两次页面测试脚本文件中的不同来确定可以进行参数化的位置。以此来获得可以进行参数化的测试项
用户确认测试项:已经获取到的测试项将以列表形式展示,需用户手动选取需要进行测试的测试项。
测试项参数化记录:记录需要参数化的测试项的页面信息,在文件中的行数,以及确认参数化位置的前后文等信息。保存于数据库中。
主要功能:
本文中需要解决的问题之一是脚本数据生成的自动化问题。如果仅仅依靠用户在指令生成模块中手动提供数据效率十分低下,不能满足自动化的要求。在银行业务中根据业务不同数据的种类繁多,类型也不尽相同。为了能够对这种情况进行测试,也应该提供多种获取数据的方式。
在WEB应用测试中,数据一般被分为两种,一种是应用数据,是指储存在WEB应用数据库中已经存在的数据,另一种是测试数据在Web应用数据库中不存在的数据。在该模块中我们要分别对他们进行处理,数据库中存储指令文件模板的所需数据类型,当用户设置某类型指令进行测试时,系统根据指定的指令生成SQL语句,查询指定数据库,从中获得数据。如果指定文件并非数据库文件,则由用户指定规则,由规则自动生成测试数据。
在这部分中,我们通过数据驱动的原则进行设计,首先解析测试项获模块获得的测试项类型,获得测试用例以及测试用例所需要的数据的类型和定义,再从指定的测试集中(数据库或自动生成的文件)选取数据,并导入LoadRunner中,由LoadRunner执行测试。工作流程:
图7
该模块如上图7主要有如下几步:
检查用户指定的测试参数和测试数据的提供方式。
判断测试数据的获取方式,如果为数据库则连接数据库,根据用户设置在数据库中查找指定的字段取出的数据。如果测试数据的获取方式为自动生成,则进入配置测试数据生成规则,根据用户设置的数据规则自动生成随机数据。如果检索数据库后没有返回测试数据,或测试数据生成失败,则返回错误信息。
配置测试数据规则,用户配置测试数据名称和测试数据生成规则。
根据数据规则设置生成数据。提供数据规则选项,由系统根据用户提供的规则自动生成随机数据。
保存数据。将获取的测试数据保存至数据库中测试数据对应的表中。
这部分用于生成脚本,这部分的功能依托于脚本模板库,由用户配置执行顺序,根据之前几步的配置调用模板库中的对应的LoadRunner脚本语句,并对其中调用的参数和模块进行初始化和参数类型归一化,生成脚本。同时,本模块也支持脚本预览和修正功能。允许用户手动添加脚本内容。当完成后,自动保存脚本,并生成XML格式的性能测试脚本。
工作流程如下图8:
图8
1. 用户配置脚本语句,读取脚本语句模板库打到对应的语句模板
2. 根据用户配置的脚本语句参数,将脚本语句模板所需要设置的脚本语句参数添加到脚本语句模板当中,构成完整的脚本语句。
3. 关联测试数据:检查数据库数据表中指定的测试数据是否存在,并将其列表显示。用户将测试数据与已经被参数化的字段进行配对,测试数据与测试参数为1:1即一个测试参数只能对应一组测试数据。
4. 生成XML测试脚本预览:脚本在预览界面中显示。
5. 需要手动编辑脚本的话,进行手动编辑。
6. 记录并保存用户手动脚本配置:允许用户在预览窗口中进行手动编辑,并对脚本合法性进行校验。
7. 将编写完成的脚本以用户指定名称输出到指定位置。
数据库采用Oracle数据库,主要保存和脚本编辑有关的设置,数据,模板等信息。
主要数据库表如下图9所示:
图9
数据库主要包括以下表格:
WebInfo:该表1主要保存与测试页面相关的信息。主要包括测试对象WEB网页连接的相关设置信息。
表1
列名 | 是否主键 | 数据类型 | 说明 |
WebId | 是 | Integer | Web配置数据的ID |
WebName | 否 | Varchar | 测试网页配置参数名 |
WebNum | 否 | Varchar | 测试网页配置参数 |
SqlInfo:此表2的作用是保存用户导入数据库的相关信息,此表主要用于从数据库中直接导入测试数据的情况,此表指明了测试数据库的位置和名字
表2
列名 | 是否主键 | 数据类型 | 说明 |
SqlId | 是 | Integer | 数据库记录ID |
SqlName | 否 | Varchar | 导入测试数据库表名 |
SqlArd | 否 | Varchar | 导入测试数据库保存路径 |
TemplateInfo:保存LoadRunner脚本模板语句的表3,用于生成脚本语句。主要保存了LoadRunner测试脚本的标准语句模板,除了保存语句本身,还保存了语句的名称(即在界面上显示的名称)和语句中包含的,需要用户进行设置的参数及其类型。
表3
列名 | 是否主键 | 数据类型 | 说明 |
TempID | 是 | INTEGER | 脚本语句模板ID号 |
TempName | 否 | VARCHAR | 脚本语句模板名 |
TempCode | 否 | VARCHAR | 脚本语句模板 |
TempPara | 否 | VARCHAR | 脚本语句模板参数 |
TempParaType | 否 | VARCHAR | 脚本语句模板参数类型 |
ParameterInfo:保存参数化字段的数据表4。此表主要保存脚本参数化的相关配置,在系统对两次运行生成的XML文件进行对比完成后,提取其中的变化部分,记录变化部分及该部分前后的关键字,作为参数化标识。同时这部分还需要调用对应参数化字段需要的测试数据ID
表4
列名 | 是否主键 | 数据类型 | 说明 |
ParId | 是 | Integer | 参数化字段的ID |
ParWeb | 否 | Varchar | 需要进行参数化的网页 |
ParHead | 否 | Varchar | 用于定位参数化字段的前端字段 |
ParTail | 否 | Varchar | 用于定位参数化字段的后端字段 |
ScriptID | 否 | Integer | 需要进行参数化的脚本名 |
RuleInfo:保存自动生成参数规则。此表5主要用于自动生成测试参数的规则,主要包括参数名称,类型,长度和生成测试数据的条数。
表5
列名 | 是否主键 | 数据类型 | 说明 |
RuleId | 是 | Integer | 自动生成参数规则 |
RuleType | 否 | VARCHAR | 生成参数类型 |
RuleLength | 否 | Integer | 生成参数长度 |
RuleNumber | 否 | Integer | 生成参数数量 |
RuleName | 否 | VARCHAR | 生成的参数名称 |
TestValue:保存测试数据。保存由系统相关方法自动数据,依据规则生成的测试数据。并记录相关数据的信息,为下一步应用测试数据提供依据和标准。生成的测试数据主要来自于数据库抽取的数据和规则生成的数据。这部分也需要调用这两个相关表的字段。
表6
列名 | 是否主键 | 数据类型 | 说明 |
ValueId | 是 | Interger | 测试数据ID号 |
Value | 否 | VARCHAR | 测试数据值 |
ValueType | 否 | VARCHAR | 测试数据参数类型 |
SqlID | 否 | Integer | 抽取测试数据的数据库ID号,0为非抽取数据 |
ParID | 否 | Integer | 使用此测试数据的参数号 |
RuleID | 否 | Integer | 生成此测试数据的规则ID号 |
FunctionStep:保存脚本语句所在位置的数据表7。设置脚本语句在脚本中的所在位置,一般以行数作为记录。
表7
列名 | 是否主键 | 数据类型 | 说明 |
FuncID | 是 | Integer | 调用脚本功能ID |
FuncName | 否 | Varchar | 调用功能名,同一功能名对应的模板在同一脚本内 |
TempID | 否 | Integer | 调用的脚本模板名 |
StepOrder | 否 | Integer | 脚本模板输入至脚本时在脚本文件内的行数。 |
ScriptInfo:保存生成脚本的信息。主要记录最终生成的测试脚本的信息,包括相关的文件名,模板名,参数名,测试数据,连接信息等。为形成最后的测试脚本提供依据。
表8
列名 | 是否主键 | 数据类型 | 说明 |
ScriptID | 是 | Integer | 生成的脚本编号 |
ScriptName | 否 | Varchar | 生成的脚本名 |
ScriptAdr | 否 | Varchar | 生成脚本的保存地址 |
WebID | 否 | Integer | 测试脚本测试对象的网页ID |
ParId | 否 | Integer | 测试脚本需要参数化的参数ID |
ValueId | 否 | Integer | 测试脚本调取的测试数据ID |
ScdId | 否 | Integer | 测试脚本配置场景ID |
FuncID | 否 | Integer | 测试脚本调用的执行顺序ID |
脚本语句列表:
脚本语句主要保存于脚本语句模板库中,通过调用方法对它们的调用和向XML脚本文件中写入,来构成完整的脚本。主要的脚本语句函数主要有:
1. web_reg_save_param("参数名","LB=左边界","RB=右边界",LAST);
注册函数,在参数值出现的前面使用,注册成功时返回值为0,注册失败时返回1。
2. lr_save_string(“字符串变量”,"参数名")/将字符变量里的值传递给指定参数。通过该函数来改变DataFile类型参数的数值。
3. lr_eval_string("{参数名}")
取得参数的数值。可取得已注册参数或DataFile类型参数的值
4. char*strcat(char*to,constchar*from);/将一字符串追加到另一字符串后面 。
5. web_find("find_time","检查点名",LAST);
增加检查点,。
6. lr_end_sub_transaction/标记子事务的结束以便进行性能分析
7. lr_end_transaction/标记LoadRunner事务的结束
8. lr_start_sub_transaction/标记子事务的开始
9. lr_start_transaction/标记事务的开始
10. lr_stop_transaction/停止事务数
11. lr_end_sub_transaction/标记子事务的结束以便进行性能分析