首页> 中国专利> 用于基于框架的应用程序的回归测试选择方法和装置

用于基于框架的应用程序的回归测试选择方法和装置

摘要

公开了一种用于基于框架的应用程序的回归测试选择方法和装置,该方法包括:通过分析修改前的应用程序的配置文件提取框架配置模型实例,其描述了该应用程序的框架配置中的各配置节点以及各配置节点中包含的代码单元之间的关系;通过对测试用例的运行使用踪迹监视构建测试用例的调用流,其包括测试用例在运行过程中所经历的程序代码单元及其控制流关系;通过将配置节点与调用流中的程序代码单元相关联,来获得测试用例的扩展调用流;以及选择其扩展调用流发生更改的测试用例,作为将重新运行的回归测试套。

著录项

  • 公开/公告号CN102110048A

    专利类型发明专利

  • 公开/公告日2011-06-29

    原文格式PDF

  • 申请/专利权人 国际商业机器公司;

    申请/专利号CN200910265277.6

  • 申请日2009-12-28

  • 分类号G06F11/36(20060101);

  • 代理机构11247 北京市中咨律师事务所;

  • 代理人于静;张亚非

  • 地址 美国纽约

  • 入库时间 2023-12-18 02:43:19

法律信息

  • 法律状态公告日

    法律状态信息

    法律状态

  • 2014-07-09

    授权

    授权

  • 2011-08-10

    实质审查的生效 IPC(主分类):G06F11/36 申请日:20091228

    实质审查的生效

  • 2011-06-29

    公开

    公开

说明书

技术领域

本发明涉及计算机领域,具体涉及计算机程序的测试,更具体涉及一种用于基于框架的应用程序的回归测试选择方法和装置。

背景技术

选择性回归测试涉及使用整个测试套(test suite)的子集来重新测试软件系统的应用程序,以验证对应用程序的修改没有对符合需求规范的现有功能造成不利影响。回归测试选择就是指从原来的整个测试套中选择用于重新测试的测试用例。用于传统的商业Java应用的传统回归测试选择方法通过获得经历纯Java代码的变化点的测试用例来生成回归测试套。在这种方法中,使用运行踪迹监视(execution trace monitor)技术来获得应用的运行踪迹,并使用诸如程序依赖图(Program Dependence Graph)、路径分析、数据流、图遍历(Graph Walk)、防火墙等静态程序分析技术来分析程序修改的影响,从而得以判断每个测试用例是否经历了受修改影响的功能,并进而选择需要进行重新运行的测试用例。

这种传统的回归测试选择方法仅适用于传统的Java应用,其中应用的逻辑仅存在于在代码中。然而,在目前流行的基于框架的应用程序-例如J2EE应用中,应用逻辑不仅存在于代码中,而且存在于框架配置文件(例如,Spring,Struts,iBatis等框架的配置文件)中。对于基于框架的应用程序来说,对程序的修改既可能发生在程序代码中,也可能发生在配置文件中。因此,回归测试用例的选择不仅应当考虑代码中的变化及其影响,而且应当考虑到配置文件的变化及其影响。而现有的回归测试选择技术只能处理代码中的变化,而不能处理配置文件中的变化。因此,现在的通常做法是当发生配置文件中的变化时,重新运行全部测试用例,这将造成耗费大量测试时间和测试资源;或者,人工选择回归测试用例,这不但很耗时,而且覆盖性较差,而很可能遗漏了那些应该进行重新测试的测试用例。

发明内容

根据本发明的一个方面,提供了一种用于基于框架的应用程序的回归测试选择方法,所述应用程序包含程序文件和配置文件,所述方法包括:在应用程序修改前,通过分析应用程序的配置文件提取框架配置模型实例,所述框架配置模型实例描述了该应用程序的框架配置中的各配置节点以及各配置节点中包含的代码单元之间的关系;通过对该应用程序的测试用例的运行使用踪迹监视,构建测试用例的调用流,所述调用流包括测试用例运行过程中所经历的程序文件中的代码单元以及代码单元之间的控制流关系;以及通过将所述框架配置模型实例中的配置节点与所述测试用例的调用流中的代码单元相关联,获得测试用例的扩展调用流。

根据本发明的另一个方面,提供了一种用于基于框架的应用程序的回归测试选择装置,所述应用程序包含程序文件和配置文件,所述装置包括:框架分析器,用于在应用程序修改前,通过分析应用程序的配置文件提取框架配置模型实例,所述框架配置模型实例描述了该应用程序的框架配置中的各配置节点以及各配置节点中包含的代码单元之间的关系;测试特征提取引擎,用于通过对该应用程序的测试用例的运行使用踪迹监视构建测试用例的调用流,所述调用流包括测试用例在运行过程中所经历的程序文件中的代码单元以及代码单元之间的控制流关系;以及节点/代码单元关联引擎,用于将所述框架配置模型实例中的配置节点与所述测试用例的调用流中的代码单元相关联,获得测试用例的扩展调用流。

本发明的技术方案通过考虑配置文件的变化的影响增强了回归测试选择,使得所选择的回归测试套具有良好的覆盖性,更为全面和实用,从而便利了基于框架的应用程序的回归测试。本发明的技术方案适用于各种框架,并可通过对不同框架的配置文件的处理自动选择回归测试用例,而不需要人工进行选择。

附图说明

所附权利要求中阐述了被认为是本发明的特点的创造性特征。但是,通过参照附图阅读下面对说明性实施例的详细说明可更好地理解发明本身以及其优选使用模式、目标、特征以及优点,在附图中:

图1示意性地例示了一个典型的J2EE应用以及配置文件中的修改对程序测试运行的影响;

图2示出了根据本发明的实施例的用于基于框架的应用程序的回归测试选择方法的流程图;

图3示意性地示出了根据本发明的实施例的用于基于框架的J2EE应用的回归测试选择方法;

图4示出了框架配置模型实例片段的示例;

图5A例示了使用现有的踪迹监视技术生成的测试用例的调用流;

图5B例示了使用本发明的关联步骤生成的测试用例的扩展调用流;以及

图6示出了根据本发明的实施例用于基于框架的J2EE应用的回归测试选择装置。

具体实施方式

本发明提供了一种用于基于框架的应用程序运行的回归测试的方法,包括如下步骤:通过分析基于框架的应用程序的配置文件提取框架配置模型实例,所述框架配置模型实例描述了该应用程序的框架配置中的各配置节点以及各配置节点中包含的代码单元之间的关系;通过运行测试套中的测试用例并使用踪迹监视构建测试用例的调用流,所述调用流包括测试用例在运行过程中所经历的程序代码单元及其控制流关系;以及通过将所述框架配置模型实例中的配置节点与所述调用流中的程序代码单元相关联,来获得测试用例的扩展调用流。

以下以J2EE应用为例,详细说明本发明的实施方式。所属技术领域的技术人员应当明白,本发明并不限于J2EE应用的特定细节,基于J2EE应用的实施方式,完全可以推广到其它基于框架的应用程序。

图1示意性地例示了一个典型的J2EE应用以及配置文件中的修改对程序测试运行的影响。如图所示,该J2EE应用具有如下6层:Web、Action、Service、DAO、Object和DB层,每层包括各自的程序代码单元。Web层为JSP。当用户通过JSP提交一个ActionForm从而与应用交互时,Struts框架将根据配置文件struts-config.xml中的配置把该ActionForm传递给Action层中特定的Action类。当该Action类执行完成后,结果字符串将根据同一个配置文件中的配置将应用引导到下一个JSP。在该图的左测,示出了5个测试用例及其调用流;在该图的右测,示出了配置片段。如本领域的技术人员所知的,测试用例的调用流是指测试用例在运行过程中所调用的程序代码单元集合以及程序代码单元之间的控制流关系。测试用例的调用流可以用调用流图来表示,该调用流图中的节点表示程序代码单元,而节点之间的边表示程序代码单元之间的控制流关系。如图1所示,测试用例1的调用流为UI1->A3->S4->D5->O3->DB2,测试用例2的调用流为UI4->A5->S5->D5->O3->DB1,测试用例3的调用流为UI1->A1->S2->D3->O2->DB1,测试用例4的调用流为UI4->A4->S5->D4->O4->DB1,测试用例5的调用流为UI2->A2->S1->D3->O1->DB1。

如图1中的配置文件片段101所示,当由“UI4action”指示的ActionForm被提交时,相关的Action类“A5”将被触发来处理该ActionForm。该操作过程的硬编码处理结果“success”将使调用流转到JSP“UI5”(未示出)。可通过更新配置文件而不是更新Java代码或JSP代码来改变该调用流。例如,如附图中所示,如果在版本v2中将版本v1中的上述配置文件片段中的“A5”修改为“A3”,则将使处理ActionForm“UI4action”的Action类从“A5”变为“A3”。这就意味着,调用流中包含UI4->A5的测试用例2需要在回归测试中重新运行(配置文件修改后测试用例2的调用流中代码单元A3之后的路径未示出)。

如图1中的配置文件片段102所示,在服务层,服务bean S2的属性是“daobean”,这是该服务bean的变量的声明。在这里,“daobean”是一个接口。服务bean动态调用该接口的实现来合成业务逻辑。在Spring框架中,依赖性查询机制使得动态绑定是可配置的。例如,Spring配置文件的XML片段指示接口“daobean”将由DAO类“D3”实例化。换言之,调用“daobean”的方法的服务S2的任何方法将被动态绑定到D3的相应实现方法。如果随着需求的变化,如图1中的配置文件片段102所示,在新版本中,该服务需要通过“D4”来合成业务逻辑,则通过将“D3”更改为“D4”来更新配置文件。为了验证该更改的正确性,通过S2中的daobean经历了D3的方法的测试用例3需要重新运行。

如图1中的配置文件片段103所示,在数据层,DAO类中的“code.getsingle”的ID引用将触发配置文件中的SQL语句“selectCODEID,CODENAME,from T_CODE where CODEID=#codeID#”的执行。假设如附图中所示,该SQL语句在新版本中被更改为“selectCODEID,CODENAME,from T_CODE”,则通过D4经历了配置文件中的该先前的SQL语句的测试用例4将具有不同的行为,因此需要重新运行来验证该更新。

在附图1所示的示例中,通过代码分析得知的程序代码中的修改只有S4,因此只会考虑重新运行经历了S4的测试用例1。这就是说,在传统的回归测试选择方法中,由于只考虑代码中的更改,因此只能选择测试用例1进行回归测试,而无法选择其他测试用例,覆盖性较差,增加了由于修改导致程序错误的风险。本发明的回归测试选择方法由于不仅考虑了程序代码中的更改,而且考虑到配置文件中的更改,因此,能够选择测试用例1、2、3、4进行回归测试,具有良好的覆盖性,可以有效地测试和纠正由于配置文件的修改可能导致的程序错误。

下面参照附图来说明本发明的实施例。在下面的说明中,阐述了许多具体细节以便更全面地了解本发明。但是,对于本技术领域内的技术人员明显的是,本发明的实现可不具有这些具体细节中的一些。此外,应当理解的是,本发明并不限于所介绍的特定实施例。相反,可以考虑用下面的特征和要素的任意组合来实施本发明,而无论它们是否涉及不同的实施例。因此,下面的方面、特征、实施例和优点仅作说明之用而不应被看作是所附权利要求的要素或限定,除非权利要求中明确提出。

下面参照图2,其示出了根据本发明的实施例的用于基于框架的应用程序的回归测试选择方法的流程图。如图所示,该方法包括以下步骤:

在步骤201,在应用程序修改前,通过分析应用程序的配置文件提取框架配置模型实例,所述框架配置模型实例描述了该应用程序的框架配置中的各配置节点及其与程序代码单元之间的关系。

在步骤202,通过运行该应用程序的测试用例并使用踪迹监视,构建测试用例的调用流,所述调用流包括测试用例运行过程中所经历的程序文件中的代码单元以及代码单元之间的控制流关系。

在步骤203,通过将所述框架配置模型实例中的配置节点与所述调用流中的代码单元相关联,来获得测试用例的扩展调用流。

可选地,在步骤204,在应用程序修改后,选择其扩展调用流发生更改的测试用例,作为将被重新运行的测试用例。

下面参照图3,其以J2EE应用为例示意性地示出了根据本发明的实施例的用于基于框架的应用程序的回归测试选择方法。如图所示,该方法包括以下步骤:

步骤1、提取框架配置模型实例。框架配置模型实例用于描述一个框架下的特定J2EE应用的配置中的各配置节点中所表示虚拟代码单元(即从配置文件中获得的代码单元)及其与程序代码单元之间的关系。所述代码单元(包含虚拟代码单元和程序代码单元)可以是代码中的类、表单请求、JSP、函数和变量等。代码单元集合可表示为ITA(IT-Artifact的缩写,表示IT制品,其中ITA可以分为两部分,一部分是程序代码单元集合CU,另一部分是虚拟代码单元集合VU),而单个代码单元可表示为ita,这里的ita可以是一个CUi(CUi表示一个程序代码单元),也可以是一个VUi(VUi表示一个虚拟代码单元)。每一个框架(例如Spring,Struts,iBatis等)都规定了属于该框架的配置文件的独特的结构、语法和语义,其可称为该框架的元模型。提取框架配置模型实例需要根据一个框架所规定的配置文件的结构、语法和语义来分析属于该框架的特定J2EE应用的配置文件,从而获得该配置文件中的各配置节点及其与程序代码单元之间的关系。对于XML格式的配置文件来说,可以将XML根节点之下的所有二级XML节点当作配置节点。例如,通过分析如下所述的Struts配置文件片段:

    <action name=“UI4action″class=“A5″><result name=″success″>

UI5</result>/action>,

可以获得如图4所示的框架配置模型实例片段。该框架配置模型实例片段包括action节点,结合Struts的语义,可以知道action节点的name属性的值表示一个ita“UI4action”,action节点的class属性的值表示一个ita“A5”,action节点的result子节点的name属性的值表示一个ita“success”,action节点的result子节点的值(VALUE)表示一个ita“UI5”。这些ITA之间隐含了由Struts语法所定义的控制流关系。

本发明将在J2EE框架配置模型实例中的所表示的虚拟代码单元与程序代码单元之间的关系归纳为5种普遍适用的类型,称为连接模式。也就是说,在任何J2EE框架中,由配置文件表示的配置节点与程序代码单元之间的关系都属于这5种连接模式中的一种或几种。这5种连接模式的形式化表示如下所示:

P1:VUi<VUj|(CUi,CUi.ID=VUi.ID)(CUj,CUj.ID=VUj.ID)

P2:VUi>VUj|(CUi,CUi.ID=VUi.ID)(CUj,CUj.ID=VUj.ID)

P3:VUi>VUj|(CUj,CUj.ID=VUj.ID)

(CUi,CUi.ID=VUi.ID(CUi,CUi.ID=VUi.IDCUi.VauleVUi.Value))

P4:VUi>VUj|(CUi,CUi.ID=VUi.ID)

(CUj,CUj.ID=VUj.ID(CUj,CUj.ID=VUj.IDCUj.ValueVUj.Value))

P5:VUi>VUj|(CUi,CUi.ID=VUi.ID)(CUj,CUj.ID=VUj.ID)

其中,VUi和VUj分别表示在配置文件中所表示的虚拟代码单元,VUi.ID和VUj.ID分别表示VUi和VUj的标识,VUi.Value和VUj.Value分别表示VUi和VUj所表示的代码片段的内容;CUi和CUj分别表示程序代码单元,CUi.ID和CUj.ID分别表示CUi和CUj的标识,CUi.Value和CUj.Value分别表示CUi和CUj的代码片段的内容。这里的ID可以是类标识、JSP标识、方法标识或字符串等。“<”表示控制反转关系(inversion ofcontrol),也就是说如果VUi和VUj符合连接模式P1,那么当调用到VUi的时候,对VUi的实际执行是通过执行VUj来实现的;“>”表示控制流方向,即当程序执行完“>”左边的代码单元后,会触发“>”右边的代码单元的调用。“|”表示该模式合法的必要条件,即只有右边的公式成立时该模式才是合法的。“∩”表示“与”的关系,即只有当运算符两边的表达式同时成立时,整个表达式才成立,“∪”表示“或”的关系,即关系两边的表达式只要有一个成立,整个表达就成立。表示存在量词,表示非存在量词。这5个连接模式所表示的具体含义如下:

连接模式P1表示了框架配置所表示的虚拟代码单元(VUi)和虚拟代码单元(VUj)之间的控制反转关系。当应用程序运行到与VUi具有相同ID的CUi时,实际上是通过与VUj具有相同的标识的CUj的执行来实现的。例如,在图1所示的配置文件片段示例102中,daobean是连接模式P1中的VUi,而D3是连接模式P1中的VUj。根据这些虚拟代码单元所属于Spring这种框架的语义可知,daobean是类S2的接口变量,而D3是该接口的实现类,daobean的执行实际上是由D3的执行来实现的。这两个虚拟代码单元在程序代码单元中都有具有相同ID的程序代码单元与之对应。

连接模式P2表示了框架所表示的VUi和VUj之间的控制流关系。在这种连接模式中,VUi和VUj在程序代码单元中都能找到具有相同ID的CUi和CUj与之对应,程序执行到VUi的时候,会触发调用与VUj具有相同ID的CUj的调用。例如,在图1所示的配置文件片段示例101中,配置文件中的虚拟代码单元“success”和UI5分别对应于程序中action函数中程序代码单元常量“success”和JSP页面UI5。这样,根据Struts这种框架的语义,在应用执行过程中,对常量“success”的访问将导致UI5的执行。在这里,“success”是连接模式P2中的VUi,而UI5是连接模式P2中的VUj,这两个VU在程序中都有对应的具有相同ID的程序代码单元,即CUi和CUj。

连接模式P3和P4表示了框架所表示的VUi和VUj之间的控制流关系,模式P3和模式P4是对称的。对连接模式P4来说,在程序代码中能够找到与VUi具有相同ID值的CUi,但是无法找到与VUj表示的虚拟代码单元相同(ID和Value都相同)的程序代码单元CUj。如果满足连接模式P4,则程序执行到与VUi对应的CUi的时候,将触发VUj的执行。例如,在图1所示的配置文件片段示例103中,根据Ibatis这种框架的语义,SQL片段的执行将由标识为code.getSingle的程序代码单元的执行所触发,所述SQL片段只出现在配置文件中。在这里,code.getSingle是连接模式P4中的VUi,所述SQL片段是连接模式P4中的VUj。这里的SQL片段在程序中没有与之对应的程序代码单元。连接模式P3与连接模式P4类似,细节省略。

连接模式P5表示这样的两个虚拟代码单元,VUi和VUj在程序代码中都没有对应的程序代码单元,框架隐含了VUi和VUj之间的控制流关系。例如,在图1所示的配置文件片段示例103中,从SQL片段的执行到SQL执行返回的SQL ResultMap。这两个单元都是只有在配置文件中才有的单元。在这里,所述SQL片段和resultMap分别是连接模块P5中的VUi和VUj。当程序执行到VUi的时候会触发VUj的调用。

由框架配置文件提取的框架配置模型实例中的每个配置节点将包含上述5种连接模式中的一个或多个。在本步骤中,结合每种框架的语义,便可以提取出框架配置模型。框架配置模型的形式化表示可以如下所示:

框架配置模型:

FC={NODE},FC表示框架配置,NODE表示一个J2EE应用的由配置文件表示的框架配置中的配置节点node的集合,其中node={id,VU,CP},node表示框架配置中的一个配置节点(例如可以是XML格式的配置文件中的XML节点),id表示该配置节点的唯一标识,VU表示该配置节点包含的虚拟代码单元集合,CP表示该配置节点所涉及的一组连接模式。

例如,对于图1中所示的框架配置文件示例,可以生成框架配置模型如下:

FC={Action,Bean,Select},其中的这三个node的具体内容如下表A所示

  ID  VU  CP  action  UI4action,A5,success,UI5  P2:UI4action>A5  P2:success>,UI5  bean  S2,service.s2,Daobean,D3  P1:S2<service.s2,  P1:Daobean<D3  select  code_getSingle,SQLFragment,  get-codse-result,java.lang.Long  P3:SQLFragment,>java.lang.Long  P4:code_getSingle>SQLFragment  P5:SQLFragment>get-codes-result

表A:框架配置模型示例

其中,SQLFragment是指图1中的配置文件片段102中的SQL语句片段,即“select CODEID,CODENAME,from T_CODE where CODEID=#codeID#”。

步骤2、混合测试用例特征获取(profiling)。该步骤的目的是获得测试套中测试用例的扩展调用流,即考虑到配置文件影响的调用流。调用流表示测试例执行过程中,执行到的ITA之间的控制流关系。

该步骤包括如下子步骤:

子步骤2.1,对测试用例的运行进行特征获取,并构建表示测试用例的行为的调用流,所述调用流包括测试用例所经历的代码中的ita及其间的控制流关系。

特征获取可以使用现有的踪迹监视技术来进行,并可借助于前文中所述的各种静态程序分析手段。优选地,特征获取可以在实际测试过程中进行,并可以通过在修改前的被测J2EE应用程序上运行测试用例来进行。

就是说,在使用各测试用例运行修改前的被测程序的过程中,使用现有的踪迹监视技术,例如通过对被测程序进行插桩,来获取每个测试用例对被测程序中的各程序代码单元的调用过程。

测试用例的调用流可以用如下测试用例模型表示:

测试用例模型:

tc=(ITA,E),tc表示测试用例的调用流,即测试用例所经历的一组代码单元以及程序代码单元之间的控制流关系,其中:

-ITA表示测试用例所经历的程序代码单元ita的集合,ita表示测试例执行中捕获的的一个程序代码单元,包括Java方法、Java类、JSP加载、HTML表单提交、javascript函数、转发映射(Forward mapping)字符串、对象关系映射(Object Relation Mapping)sql语句等。在该子步骤2.1中构建的调用流中,ITA仅包含程序代码单元,而在下述子步骤2.2中形成的扩展调用流中,ITA可能同时包含虚拟代码单元和程序代码单元。

-E表示从这个测试例中所有的ita.pre到ita,或者ita到ita.suc的控制流关系的集合,其中,前驱程序单元ita.pre的执行将导致ita的执行,ita的执行将导致后继程序单元ita.suc的执行。例如,对于图1中所示的测试用例2,通过踪迹监视技术生成的调用流tc为UI4->A5->S5->D5->O3->DB1,其中UI4、A5、S5、D5、O3、DB1为各ita,而它们之间的有向箭头表示这些ita之间的控制流。所以E就是控制流关系集合{UI4->A5,A5->S5,S5->D5,D5->O3,O3->DB1}。以A5为例,UI4就是A5的前驱程序单元A5.pre,S5就是A5的后继程序单元A5.suc。

子步骤2.2,将配置节点与程序代码单元相关联。就是说,根据前述生成的框架配置模型中各配置节点包含的连接模式,将该连接模式涉及的虚拟代码单元或边添加到上述测试用例的调用流中,从而形成测试用例的扩展调用流,该扩展调用流不仅包含了测试用例对程序代码中各单元的调用过程,而且考虑了配置文件对该调用过程的影响。

根据本发明的一实施例,该关联子步骤可以对一个测试用例的调用流tc使用如下关联算法执行来获得这个tc的扩展调用流:

1)对于框架配置FC中的每个节点,遍历该节点的所有连接模式,并根据不同的连接模式分别进行到步骤2)、3)、4)、5)。

2)对于连接模式P1,假设CUi是tc中与FC中的VUi匹配(即具有相同的ID)的程序代码单元,CUj是tc中与FC中的VUj匹配的程序代码单元。根据该模式所表示的涵义,程序中对CUi的调用是通过对CUj的调用来实现的。因此,添加一个从CUi到CUj的边(边表示两个代码单元之间的控制流关系),以表示VUi和VUj之间的控制反转关系。例如,参看表A,在图1所示的示例配置文件片段102中,D3是VUj,daobean是VUi,service.s2调用daobean的时候实际上是调用了D3,但使用现有的踪迹监视技术只能获得service.s2调用了daobean。这里,测试用例3的tc中的D3就是CUj,即匹配VUj的程序代码单元,tc中的daobean就是CUi,即匹配VUi的程序代码单元,因此需要在tc中添加一个从CUi到CUj的边,即从daobean到D3的边来表示这个隐含的调用(应指出的是,图1中左侧示出的测试用例3的调用流中的S2->D3实际上是S2->daobean->D3的省略表示)。

3)对于连接模式P2,假设tc中的CUj是与FC中的VUj匹配的程序代码单元,CUi是与FC中的VUi匹配的程序代码单元。如果在tc中存在CUi,则添加从CUi到CUj的边。如果在tc中不存在CUi,则首先在tc中添加CUi,然后去掉CUj的前驱节点CUj.pre到CUj的边,并添加从CUj.pre到CUi的边,最后添加从CUi到CUj的边。例如,在图1所示的示例配置文件片段101中,UI4action是VUi,A5是VUj,表示当调用了UI4action后会触发调用A5。这两个虚拟代码单元在程序中都有对应的程序代码单元,但在程序中不知道它们之间的调用关系(因为它们之间的调用关系是在配置文件中指定的,而不是在程序中指定的),因此需要在tc中对应的程序代码单元之间添加一条边以表示它们之间的调用关系;如果在tc中还不存在UI4action,则需要首先在tc中添加UI4action,删除A5的前驱节点(例如UI4)到A5的边,添加A5的前驱节点到UI4action的边,以及UI4action到A5的边。

4)对于连接模式P3,在tc中添加一个新的VUi。假设tc中的CUj是与VUj匹配的程序代码单元,添加从VUi到CUj的边。

5)对于连接模式P4,在tc中添加一个新的VUj。假设tc中的CUi是与VUi匹配的程序代码单元,添加从CUi到VUj的边。例如,在图1所示的示例配置文件片段103中,code.getSingle为VUi,在tc中的code.getSingle是与该VUi对应的CUi,其执行实际上会调用到配置文件片段中的SQL代码单元(SQLFragment)这个VUj。由于在tc不存在与该VUj对应的程序代码单元CUj,因此需要在tc中添加一个新的VUj,即SQL代码单元,并添加从CUi到该VUj的边来表示这个隐藏的控制流关系。

6)对于连接模式P5,如果VUi和VUj都已存在于tc中(例如,通过以上算法步骤已将VUi和VUj添加到tc中),则添加一个从VUi到VUj的边;如果VUi和VUj中的一个尚不存在于tc中,则首先在tc中添加该不存在的VUi或VUj,然后再添加一个从VUi到VUj的边。例如,在图1所示的示例配置文件片段103中,对于SQL单元和resultMap这对遵循连接模式P5的VUi和VUj,由于在上述针对连接模式P4的处理中已经将SQL单元添加到tc中,因此这里只需要将resultMap这个VUj添加到tc中,然后添加从SQL单元到resultMap的边以表示从VUi到VUj之间的控制流关系。

7)输出最后得到的tc,作为该测试用例的扩展调用流。

例如,对于图1中所示的测试用例2,在扩展前的子步骤2.1中生成的调用流是UI4->A5->S5->D5->O3->DB1。在关联子步骤2.2中,针对该调用流应用UI4action->A5这个连接模式P2,其中UI4action是VUi,A5是VUj。VUi和VUj在程序中都有对应的程序代码单元,但在程序中不知道它们之间的调用关系,因此需要在调用流中对应的程序代码单元之间添加一条边以表示它们之间的调用关系(如果在该测试用例的调用流中UI4action还不存在,则需要首先在调用流中添加UI4action,删除A5的前驱节点到A5的边,添加A5的前驱节点到UI4action的边,然后添加UI4action到A5的边),以表示当UI4调用A5时,是因为调用了UI4action后会触发调用A5。这样,最后获得的扩展调用流为:UI4->U14action->A5->S5->D5->O3->DB1

以上描述了用于建立配置节点与程序代码单元之间的关联的一个特定的具体算法,应指出的是,上述描述中的细节仅为示例,而不是对本发明的限制。

现参照图5A和图5B,图5A例示了使用现有的踪迹监视技术生成的测试用例的调用流,其中,B1表示在被测程序修改之前该测试用例的调用流,B2表示在被测程序被修改之后所预计的该测试用例的调用流;图5B例示了使用本发明的关联步骤生成的该测试用例的扩展调用流,其中,B3表示在被测程序修改之前该测试用例的扩展调用流,B4表示在被测程序修改之后所预计的该测试用例的扩展调用流。如图5A所示,在B1和B2中,由于被测程序的代码未作修改,同时没有考虑到配置文件的修改的影响,因此,错误地预计程序修改后的调用流B2与程序修改前的调用流B是相同的,从而不会选择该测试用例来重新运行。然而,如图5B所示,在B3中,由于添加了来自配置文件的虚拟代码单元UI4action及其与程序代码单元A5之间的边,这样,当修改了配置文件后,UI4action将控制流流向A3而不是A5,调用流B3在新的版本中就应该变为B4示意的调用流,这样,就可以正确地反映该测试用例的调用流在新的版本中将会改变,从而使测试者能够选择该测试用例来进行回归测试。

步骤3、统一更改识别

在该步骤中,通过静态分析原程序P和修改后的程序P’来识别程序中的修改,然后识别这些修改对测试用例的扩展调用流的影响。程序中的修改分为两类:语言级别的修改(LLM),即程序代码中的修改,以及配置级别的修改(CLM),即配置文件中的修改。这两类修改都可能影响到测试用例的扩展调用流。无论是LLM还是CLM,它们对测试用例的扩展调用流的影响包括对tc中的ita的更改,以及对ita之间的边的更改。本发明提出的统一更改识别方法遵循以下公式:

统一更改={ITA更改∪边更改}

ITA更改={C1∪C2}

C1={ITA|ita属于CU且ita.value已被更改}

C2={ITA|ita是VUi且VUi.value已被更改}

边更改={C3∪C4∪C5∪C6},在计算前需要按照步骤1的方法生成与P’对应的框架配置模型实例FC’

C3:{edgeij|edgeij指示VUi流向VUj的控制流关系的边,其中VUi或者VUj两者之一在CU中能够找到与之对应的CUi或者CUj。在与P’对应的FC’中,VUi流向VUj的控制流关系的边上的虚拟节点VUi或VUj已被修改为VUi’或VUj’}

C4:{edgeij|edgeij指示VUi流向VUj的控制流关系的边,其中VUi和VUj在CU中都能够找到与之对应的CUi和CUj,在P与’对应的FC’中,VUi流向VUj的控制流关系的边上的虚拟节点VUi或VUj被修改为VUi’或VUj}  

C5:{edgeij|edgeij指示VUi流向VUj的控制流关系的边,其中VUi和VUj在CU中都没有与之对应的CUi和CUj,在P’对应的FC’中,VUi流向VUj的控制流关系的边上的虚拟节点VUi或VUj被修改为VUi’或VUj}

C6:{edgeij|edgeij指示VUi流向VUj的控制流关系的边,在P’对应的FC’中,没有一条VUi’流向VUj’的控制流关系的边使得VUi’=VUi或者VUj’=VUj,也就是说,这条边在新的FC’中已经完全被删除,其中没有任何一个连接模式中包含VUi或者VUj}

该步骤包括如下子步骤:

子步骤3.1,通过静态分析原程序文件和修改后的程序文件识别代码的更改。所有导致应用逻辑变化的语言代码的修改都被识别。该子步骤可使用现有的静态程序分析和比较方法来完成。

例如,类成员方法中使用的公开成员变量的初始化变化将被认为是程序变化。对于显式地经历被删除或添加的方法的测试用例来说,一定存在被删除或添加的调用入口,因此,将只考虑调用入口的删除或添加,而不再考虑方法的删除或添加。成员变量的名称变化,注解的添加、删除和修改,以及格式调整将不会造成应用逻辑的变化,因此也不予考虑。应注意的是,父类的方法变化将不会为每一个子类重新识别,因为对于子类中继承方法的调用来说,踪迹监视方法将记录父类方法调用,这样,在回归测试选择中将不会忽略任何变化的方法执行。

子步骤3.2,通过分析和比较被测J2EE应用的原配置文件和修改后的配置文件识别被测J2EE应用的配置更改。在该子步骤中,可以首先使用如以上步骤一中所述的方法根据原配置文件和修改后的配置文件分别构建修改前后的被测J2EE应用的框架配置模型实例,然后通过比较修改前后的框架配置模型实例来识别框架配置中的更改,如配置节点中的虚拟代码单元的更改、替换等。

子步骤3.3,确定所识别的代码更改和配置更改对每个测试用例的扩展调用流的影响。

对于所识别的代码更改来说,需要判断每个测试用例的扩展调用流中是否包含了更改的程序代码单元。只要该扩展调用流包含了更改的程序代码单元,则该扩展调用流就受到该更改的影响,因此,该测试用例需要重新运行以进行回归测试。这样的代码更改即为C1。

对于所识别的配置更改来说,需要根据所识别的配置更改确定每个测试用例的扩展调用流中是否存在相应变化。具体地,根据所识别的配置更改确定每个测试用例的扩展调用流中是否存在如下5种类型的变化,即由CLM造成的C2、C3、C4、C5和C6:

由CLM造成的C2,这是由配置更改造成的虚拟代码单元的内部变化,即对VUi的值的更改。例如,在配置文件中将VUi的值从“select CODEID,CODENAME,from T_CODE where CODEID=#codeID#”修改为“selectCODEID,CODENAME,from T_CODE where CODEID”。这样,在测试用例的扩展调用流中该VUi就被标识为已更改。

由CLM造成的C3,即由配置更改造成的测试用例的扩展调用流中与VUi到VUj控制流对应的边的变化,其中边的一个节点有程序代码单元与之对应,另一个节点没有程序代码单元与之对应,此时当VUi到VUj的控制流对应的边上的两个节点在FC’中有一个发生更新时,这条边需要被视为已修改。应注意的是,C3对应于上述连接模式P3和P4。

由CLM造成的C4,即由配置更改造成的测试用例的扩展调用流中与VUi到VUj控制流对应的边的变化,其中边的两个节点都有程序代码单元与之对应,此时当VUi到VUj控制流对应的边上的两个节点在FC’中有一个发生更新时,这条边需要被视为已修改。应注意的是,C4对应于上述连接模式P1和P2。对于连接模式P1来说,如果在运行时实现VUi的VUj被更新为VUj’,则在修改后的程序中VUi的执行将通过对VUj’的调用来实现。因此,测试用例的扩展调用流中从VUi到VUj的边(也即为对应的CUi到CUj的边)应当被标识为变化的边。例如,如果VUi“daobean”的实现类从VUj“D3”更新为VUj’“D4”,则任何测试用例的扩展调用流中存在的边“daobean->D3”应当被标识为已更改。对于连接模式P2,假设是VUj在FC’中被更新为VUj,那么该更新将使得在修改后的程序中从VUi到VUj的流程流向VUj’。例如,将A5修改为A3将导致在修改后的程序中由U14action流向A3。

由CLM造成的C5,即由配置更改造成的测试用例的扩展调用流中的边的变化,其中边的虚拟代码单元在CU中都找不到对应的程序代码单元,在新的FC’中这条边上的一个虚拟代码单元已被修改。应注意的是,C4对应于上述连接模式P5。例如,如果在FC’中,VUj“Get-Code-Result”被修改为新的VUj’“Get-Code-Result-new”,则在修改后的程序的调用流中当执行到SQL代码单元(即VUi)后,将调用“Get-Code-Result-new”,因此可以认为从SQL代码单元到“Get-Code-Result”的边已发生更改。

应指出的是,以上由CLM造成的变化C3、C4和C5可被概括为由配置更改造成的扩展调用流中的边的变化,其中,边的一个节点被更改。

由CLM造成的C6,即在配置更改后,这条边在新的FC’中已经完全被删除,在FC’中没有任何一个连接模式中包含VUi或者VUj,那么这条边应被视为发生更改。

只要该扩展调用流包含了上述6种类型的变化中的任何一个或多个变化,则该扩展调用流就受到该更改的影响,因此,该扩展调用流对应的测试用例需要重新运行以进行回归测试。

步骤4、测试用例选择。该步骤从全部测试用例中选择那些其扩展调用流中发生变化的测试用例,即包含了上述变化类型C1、C2、C3、C4、C5和C6中的任何变化的测试用例,作为将要重新运行的回归测试套。也就是说,任何测试用例,只要其经历的程序代码单元或虚拟代码单元发生变化,或者其经历的连接两个虚拟代码单元的边在新的FC’中发生变化,或者这条边在新的FC’中被删除,则该测试用例都将被选入将重新运行的回归测试套。以上描述了根据本发明的实施例的用于基于框架的J2EE应用的回归测试选择方法,应指出的是,以上描述仅是对本发明的实施例的示例性说明,而不是对本发明的限制。本发明的方法可具有更多、更少或不同的步骤,一些步骤之间可具有与所描述不同的顺序,一些步骤可合并为更大的步骤,或划分为更小的步骤,等等。所有这些变化都处于本发明的范围之内。

在相同的发明构思下,本发明提供一种用于基于框架的应用程序的回归测试选择装置,包括:框架分析器,用于通过分析修改前的基于框架的应用程序的配置文件提取框架配置模型实例,所述框架配置模型实例描述了该应用程序的框架配置中的各配置节点及其与程序代码单元之间的关系;测试特征提取引擎,用于通过运行测试用例并使用踪迹监视构建每个测试用例的调用流,所述调用流包括测试用例在运行过程中所经历的程序代码单元及其控制流关系;以及节点/代码单元关联引擎,用于通过将所述框架配置模型实例中的配置节点与所述调用流中的程序代码单元相关联,来获得每个测试用例的扩展调用流。

下面参照附图6,以J2EE应用作为应用程序的例子,描述根据本发明的实施例的用于基于框架的应用程序的回归测试选择装置。为简明起见,在以下描述中,省略了与以上描述重复的部分细节,因此,可参见以上描述获得对本发明的增强回归测试选择装置的更详细的了解。

如附图6所示,根据本发明的实施例的用于基于框架的应用程序(例如J2EE应用)的回归测试选择装置包括如下部件:测试特征提取引擎601,框架分析器602,代码更改分析器603,节点/代码单元关联引擎604,更改/测试映射引擎605,以及可选的回归测试套选择器606。

测试特征提取引擎601用于在测试用例的测试执行过程中获取每个测试用例的调用流,即测试用例在被测J2EE应用中所调用的各程序单元及其控制流。所述被测J2EE应用为修改前的被测J2EE应用。该测试特征提取引擎601可通过现有的踪迹监视工具以及静态程序分析技术来实现。

框架分析器602用于从J2EE应用的框架配置文件中构建该J2EE应用的框架配置模型,所述构架配置模型反映了J2EE应用的框架配置中的各配置节点及其包含的代码单元之间的关系,即每个配置节点涉及的连接模式。框架分析器602需要根据特定J2EE框架所规定的配置文件的特定结构、语法和语义来构建框架配置模型。特定J2EE框架(例如,Spring,Struts,iBatis等)所规定的配置文件的特定结构、语法和语义也可称为该框架的元模型。在框架分析器602能够对属于特定框架的框架配置文件进行处理之前,首先可以使用该框架的元模型对框架分析器602进行配置,这样框架分析器602就能够根据该框架的元模型对属于该框架的框架配置文件进行分析,从而构建所述框架配置模型。对于每一种框架,仅需对框架分析器602配置一次。

所述J2EE应用的框架配置中的各配置节点与程序代码单元之间的关系选自如下5种连接模式:

P1:VUi<VUj|(CUi,CUi.ID=VUi.ID)(CUj,CUj.ID=VUj.ID)

P2:VUi>VUj|(CUi,CUi.ID=VUi.ID)(CUj,CUj.ID=VUj.ID)

P3:VUi>VUj|(CUj,CUj.ID=VUj.ID)

(CUi,CUi.ID=VUi.ID(CUi,CUi.ID=VUi.IDCUi.VauleVUi.Value))

P4:VUi>VUj|(CUi,CUi.ID=VUi.ID)

(CUj,CUj.ID=VUj.ID(CUj,CUj.ID=VUj.IDCUj.ValueVUj.Value))

P5:VUi>VUj|(CUi,CUi.ID=VUi.ID)(CUj,CUj.ID=VUj.ID)

其中,VUi和VUj分别表示在配置文件中所表示的虚拟代码单元,VUi.ID和VUj.ID分别表示VUi和VUj的标识,VUi.Value和VUj.Value分别表示VUi和VUj所表示的代码片段的内容;CUi和CUj分别表示程序代码单元,CUi.ID和CUj.ID分别表示CUi和CUj的标识,CUi.Value和CUj.Value分别表示CUi和CUj的代码片段的内容;“<”表示控制反转关系,“>”表示控制流方向,“|”表示模式合法的必要条件,“∩”表示“与”的关系,“∪”表示“或”的关系,表示存在量词,表示非存在量词。

节点/代码单元关联引擎604用于将所述框架配置模型实例中的配置节点与所述调用流中的程序代码单元相关联,从而获得每个测试用例的扩展调用流。具体地,节点/代码单元关联引擎604可根据所构建的框架配置模型中各配置节点的连接模式将相应的虚拟代码单元或边添加到每个测试用例的调用流中,从而形成每个测试用例的扩展调用流。例如,节点/代码单元关联引擎604可执行以下操作:

对于连接模式P1,假设CUi是tc与FC中的VUi匹配的程序代码单元,CUj是tc与FC中的VUj匹配的程序代码单元.根据该模式所表示的涵义,程序中对CUi的调用是通过对CUj的调用来实现的。那么则添加一个从CUi到CUj的边(边就表示了两个代码单元之间的控制流关系),以表示VUi和VUj之间的控制翻转关系。

对于连接模式P2,假设tc中的CUj是与模式中VUj匹配的程序代码单元,CUi是与模式中VUi匹配的程序代码单元。如果在所述调用流中存在CUi,则在所述调用流中添加从CUi到CUj的边;如果在tc中还不存在CUi,则首先在tc中添加CUi,然后去掉CUj的前驱节点CUj.pre到CUj的边,并添加从CUj.pre到CUi的边,最后添加从CUi到CUj的边。

对于连接模式P3,在tc中添加一个新的VUi。假设tc中的CUj是与VUj匹配的程序代码单元,添加从VUi到CUj的边。

对于连接模式P4,在tc中添加一个新的VUj。假设tc中的CUi是与VUi匹配的程序代码单元,添加从CUi到VUj的边。

对于连接模式P5,如果VUi和VUj都已存在于tc中,则添加一个从VUi到VUj的边;如果VUi和VUj中的一个尚不存在于tc中,则首先在tc中添加该不存在的VUi或VUj,然后再添加一个从VUi到VUj的边。

最后输出得到的tc,作为该测试用例的扩展调用流。

可选地,节点/代码单元关联引擎604可以将所形成的每个测试用例的扩展调用流存储在一测试储存库中。

代码更改分析器603用于分析和比较修改前后的被测J2EE应用的程序文件,并识别任何导致应用逻辑变化的程序代码单元的更改。代码更改分析器603可以使用现有的程序代码分析和比较工具来实现。

所述框架分析器602还用于分析和比较修改前后的被测J2EE应用的配置文件,并识别被测J2EE应用的配置更改。框架分析器602可以首先根据修改前后的被测J2EE应用的配置文件分别构建修改前后的J2EE应用的框架配置模型,并通过比较修改前后的J2EE应用的框架配置模型来识别框架配置模型中的更改,如配置节点中的虚拟代码单元的更改、替换等。

所述更改/测试映射引擎605用于确定所述程序代码单元的更改和配置更改对每个测试用例的扩展调用流的影响。具体地,所述更改/测试映射引擎605可通过将所识别的程序代码单元的更改和配置更改映射到每个测试用例的扩展调用流,来确定所述程序代码单元的更改和配置更改对每个测试用例的扩展调用流的影响。

确定程序代码单元的更改对每个测试用例的扩展调用流的影响包括确定每个测试用例的扩展调用流是否包含了所述更改的程序代码单元。

确定配置更改对每个测试用例的扩展调用流的影响包括根据所述配置更改确定扩展调用流中是否存在相应变化。具体地说,更改/测试引擎确定每个测试用例的扩展调用流是否包含了如下三种类型的变化中的一个或多个变化:由配置更改造成的扩展调用流中包含的虚拟代码单元的内部变化;由配置更改造成的测试用例的扩展调用流中的边的变化,其中,边的一个节点被更改;由配置更改造成的由配置更改造成的测试用例的扩展调用流中的边的删除。

所述测试套选择器606用于从全部测试用例中选择那些其扩展调用流受到所识别的代码更改和配置更改影响从而发生变化的测试用例,作为将被重新运行的测试用例。

以上描述了根据本发明的实施例的用于基于框架的应用程序的回归测试选择装置,应指出的是,以上描述仅是对本发明的实施例的示例性说明,而不是对本发明的限制。本发明的装置可具有更多、更少或不同的模块,各模块之间可具有与所描述不同的关系,一些模块可合并为更大的模块,或划分为更小的模块,等等。所有这些变化都处于本发明的范围之内。此外,各模块的名称仅为叙述方便而定,而不是对本发明的限制。

尽管以上以基于框架的J2EE应用为例描述了本发明的方法和装置,但本发明的基本思想并不仅限于J2EE应用,而是可适用于任何语言的基于框架的应用的回归测试选择。

本发明可以硬件、软件、或硬件与软件的结合的方式实现。本发明可以集中的方式在一个计算机系统中实现,或以分布方式实现,在这种分布方式中,不同的部件分布在若干互连的计算机系统中。适于执行本文中描述的方法的任何计算机系统或其它装置都是合适的。一种典型的硬件和软件的组合可以是带有计算机程序的通用计算机系统,当该计算机程序被加载和执行时,控制该计算机系统而使其执行本发明的方法,并构成本发明的装置。

本发明也可体现在计算机程序产品中,该程序产品包含使能实现本文中描述的方法的所有特征,并且当其被加载到计算机系统中时,能够执行所述方法。

尽管已参照优选实施例具体示出和说明了本发明,但是本领域内的那些技术人员应理解,可在形式和细节上对其进行各种改变而不会背离本发明的精神和范围。

去获取专利,查看全文>

相似文献

  • 专利
  • 中文文献
  • 外文文献
获取专利

客服邮箱:kefu@zhangqiaokeyan.com

京公网安备:11010802029741号 ICP备案号:京ICP备15016152号-6 六维联合信息科技 (北京) 有限公司©版权所有
  • 客服微信

  • 服务号