程序逻辑结构图示方法及程序路径统计方法

文档序号:6530550阅读:663来源:国知局
专利名称:程序逻辑结构图示方法及程序路径统计方法
技术领域
本发明涉及软件开发领域,具体地说,涉及软件开发领域的详细设计和程序测试领域,更具体地,涉及详细设计和程序测试领域的程序逻辑结构图示方法,以及程序测试领域的程序路径统计方法。
背景技术
详细设计和程序测试是软件开发过程的两个重要阶段。详细设计针对目标系统进行比较详细的说明;程序测试一般分为黑盒测试和白盒测试,其中白盒测试依据程序的内部逻辑结构设计测试用例进行测试。虽然目前很多软件从总体上来说是面向对象的,但其局部代码还是结构化的,详细设计和白盒测试常常需要画出局部程序的逻辑结构的图示。
目前常用的程序逻辑结构图示方法是利用绘图工具软件,使用逻辑结构图的图形符号,画出程序逻辑结构图。常用的逻辑结构图有三种,程序流程图、盒图(N-S图)、PAD图,它们常用的部分图形符号如图2所示,其中图2A是程序流程图的部分图形符号,201为选择(分支),202为处理,203为开始或停止,204为预先定义的处理,205为输入输出,206为控制流;图2B是盒图的部分图形符号,211为顺序,212为条件,213为循环,214为调用子程序A;图2C是PAD图的部分图形符号,221为顺序,222为循环(WHILE C DO P),223为选择(IFC THEN P1 ELSE P2),224为定义。
图3是对应于图1A所示的示例代码的程序流程图。程序流程图是历史最悠久、使用最广泛的描述程序过程的工具,具有不利于逐步求精、不利于遵循结构程序设计的精神、不易表示数据结构等缺点。
图4是对应于图1A所示的示例代码的盒图。盒图具有功能域明确、不可能任意转移控制、容易确定局部和全部数据的作用域、容易表现嵌套关系和模块的层次结构等特点,但当程序结构较复杂时,盒图的绘制比较困难。
图5是对应于图1A所示的示例代码的PAD图。PAD是问题分析图(problem analysis diagram)的英文缩写,它用二维树形结构的图来表示程序的控制结构,将这种图翻译成程序代码比较容易,并且结构清晰、易读易懂易记,支持自顶向下、逐步求精的设计方法。
上述的程序逻辑结构图示方法使用图形符号画出程序逻辑结构图,效率较低,尤其是程序逻辑较复杂时,需要花费较长的绘图时间,修改逻辑结构图也比较麻烦。另一方面,所获得的逻辑结构图在用于程序测试时有较大缺陷,都难于描述程序路径,也难于自动统计程序路径。目前的测试工作中,当要分析程序路径时,一般要另外画出控制流图,增加了工作量。另外,控制流图在描述程序路径时也不够直观,并且不便于自动统计路径。
白盒测试方法针对代码的内部逻辑结构设计测试用例,使用逻辑覆盖作为测试度量,逻辑覆盖有语句覆盖、判定覆盖、条件覆盖、判定条件覆盖、路径覆盖等。不同的逻辑覆盖具有不同的测试完整性,其中路径覆盖是白盒测试最为经典的问题,具有很好的测试完整性。由于程序中含有循环结构时,一个很简单的程序都可能产生大量的路径,完全的路径覆盖在实际的测试工作中不具实用性,因此,统计路径时一般不考虑循环的实际次数,只考虑执行循环体和不执行循环体两种情况,这种简化的路径覆盖又叫Z路径覆盖,由于完全的路径覆盖不具实用性,我们所说的路径覆盖是指Z路径覆盖。
路径覆盖具有很好的测试完整性,但在实际测试中却很少使用,主要原因是测试成本太高,造成测试成本高的原因主要有两点缺少自动统计路径的方法和工具;由于任何分支都可能使路径数量倍增,当程序较复杂时路径的数量巨大。
关于路径统计,《软件测试技术概论》(39-40页,上海艾微软件技术有限公司主编,清华大学出版社出版,2004年4月第一版)一书中提到一种统计方法用路径树来表示程序的所有路径,然后从根结点开始,一次遍历,再回到根结点后,把所经历的叶结点名排列起来,就得到一个路径,如果设法遍历了所有的叶结点,就得到了所有的路径。该书未详细说明具体的实施步骤。路径树常用于在网络技术中计算路由,例如描述数据包在网络中的树形转发路径。依据该书所述的方法,人工画出路径树,并设法用人工计算路径,可能是可行的,但工作量较大。我们未检索到依据程序代码自动生成路径树的方法,目前软件市场上也未发现依据程序代码自动生成路径树的工具,也没有检索到进一步自动统计程序路径的方法,也未在软件市场上发现自动统计程序路径的工具。
关于程序较复杂时路径数量巨大,导致路径覆盖难于实施的问题,现有技术中没有较好的解决办法。
如上所述,目前的程序逻辑结构图示方法效率较低,所得到的逻辑结构图在用于程序测试时具有较大缺陷。目前路径覆盖测试缺少自动统计路径的方法,也存在当程序较复杂时路径数量过大的问题。

发明内容
本发明要解决的技术问题是针对上述的程序逻辑结构图示方法的不足之处,提出一种新的程序逻辑结构图示方法。
本发明要解决的另一个技术问题是提出一种程序路径自动统计方法。
为了解决上述第一个技术问题,本发明提出了如下技术方案一种程序逻辑结构图示方法,其特征在于,包括步骤A.生成一个顶层分支对象;B.在任意层次的分支对象中嵌套分支树对象和/或语句块对象;C.计算上述各对象的尺寸及位置并画出其图示。
还可以进一步包括用于在分支树对象中添加分支的步骤;用于在分支树对象中删除选定分支的步骤;用于修改分支判定的步骤;用于编辑语句块对象的代码的步骤;用于隐藏对象和/或显示对象的步骤;用于由逻辑结构图生成程序代码的步骤。
为了解决上述另一个技术问题,本发明提出了如下技术方案一种统计程序路径的方法,其特征在于,用统计程序路径的步骤代替上述技术方案中的步骤C。
本发明提出的程序结构图示方法,使用结构对象作为绘图单位,通过添加结构对象即可以堆砌出逻辑结构图,对象的尺寸和位置自动计算,可以快速设计出程序逻辑结构图,逻辑结构图便于修改,并与代码可以双向生成。该逻辑结构图可以直观表现程序的执行路径,还可直接用于统计程序路径,程序测试时无须另画其他图示,减少了工作量。
本发明提出的程序路径统计方法,自动统计程序路径,依据统计结果即可设计路径覆盖测试用例。当程序较复杂时,可以隐藏部分对象,统计路径时忽略已隐藏的对象,以压缩路径数量,提高路径覆盖测试的实用性。


下面结合附图对本发明的具体实施方式
作进一步详细的说明图1是示例代码及示例代码的结构划分示意图和代码片划分示意图,其中图1A是示例代码,图1B是示例代码的结构划分示意图,图1C是示例代码的代码片划分示意图。
图2是背景技术中所述三种逻辑结构图的部分图形符号。其中图2A是程序流程图的部分图形符号;图2B是盒图的部分图形符号;图2C是PAD图的部分图形符号。
图3是对应于图1A所示的示例代码的程序流程图。
图4是对应于图1A所示的示例代码的盒图。
图5是对应于图1A所示的示例代码的PAD图。
图6是本发明的一个实施例的总体流程图。
图7是在本发明的一个实施例,各结构对象的内部数据构成示意图及结构对象树示意图,其中图7A是语句块对象的内部数据构成示意图,图7B是分支树对象的内部数据构成示意图,图7C是分支对象的内部数据构成示意图,图7D是结构对象树示意图。
图8是在本发明的一个实施例,各结构对象的图示的示意图,其中图8A是分支对象的图示的示意图,图8B是另一种分支对象的图示的示意图,图8C、图8D、图8E、图8F、图8G、图8H是分支树对象的图示的示意图,图8I是语句块对象的图示的示意图。
图9是在本发明的一个实施例,画出程序逻辑结构图的过程的示意图,图9A至图9D示出了画出对应于图1B所示代码的逻辑结构图的各步骤。
图10是在本发明的一个实施例,各对象的尺寸、位置和基本尺寸的示意图。
图11是在本发明的一个实施例,计算各对象的宽度和高度的流程示意图,其中图11A是计算语句块对象的宽度和高度的流程示意图,图11B是计算分支对象的宽度和高度的流程示意图,图11C是计算分支树对象的宽度和高度的流程示意图。
图12是在本发明的一个实施例,计算各对象底座高度及分支树对象入口线高度的流程示意图,其中图12A是计算语句块对象底座高度的流程示意图,图12B是计算分支对象底座高度的流程示意图,图12C是计算分支树对象底座高度的流程示意图,图12D是计算分支树对象的入口线高度的流程示意图。
图13是在本发明的一个实施例,画出各对象图示的示意图,其中图13A是画出分支对象图示的示意图,图13B是画出另一种分支对象图示的示意图,增加了分支标注,图13C是画出分支树对象图示的示意图,图13D是画出语句块对象图示的示意图。
图14是在本发明的一个实施例,对部分图示的改进及画出隐藏对象的图示的示意图。
图15是在本发明的另一个实施例,将代码片映射为结构对象的流程示意图。
图16是在本发明的再一个实施例,统计程序路径的流程示意图,其中,图16A是当对象为语句块时统计路径的流程示意图,图16B是当对象为分支时统计路径的流程示意图,图16C是当对象为分支树时统计路径的流程示意图。
图17是逻辑结构图示出程序路径的示意图。
具体实施例方式
图6是本发明的一个实施例的总体流程图,如图6所示,步骤A生成一个顶层分支对象,步骤B在任意层次的分支对象中嵌套分支树对象和/或语句块对象;步骤C计算上述各对象的尺寸及位置并画出其图示。下面详细描述图6所示的各步骤所涉及的一些名词和用语的具体含义,然后再对各步骤的具体实施过程作详细描述。
本实施例把程序逻辑结构分为两种顺序结构和分支结构。顺序结构对应于一个语句序列,在这个语句序列中,如果第一条语句执行了,那么在没有发生异常,也未因返回语句提前返回的情况下,其他所有语句也会执行,符合这一条件的所有连续的语句应视为属于同一个顺序结构而不能分拆,即不能把其中的一部分视为属于一个顺序结构,把另一部分视为属于另一个顺序结构。顺序结构具有一个入口点和一个出口点,其入口点为结构中的第一条语句,出口点为结构中的最后一条语句,但如果顺序结构中的某条语句是返回语句(如C++的return语句),执行到该语句时函数即返回,后面的语句不会执行,实际上,后面的语句是无效的,因此,该语句是该顺序结构的实际出口点。由于GOTO语句(如C++的goto语句)破坏了结构化设计并且在当今的开发中使用越来越少,因此,本实施例不考虑GOTO语句。
分支结构对应于一个语句序列,在这个语句序列中,含有判断和/或跳转语句或类似功能的语句,在不同的条件下,可能会执行或不执行或重复执行其中的某些语句。最典型的分支结构是选择结构,循环结构也属于分支结构。由于分支结构在不同的条件下会执行或不执行或重复执行某些语句,所以,分支结构至少包含两种可能的执行路线,这些执行路线叫做分支,也就是说,一个分支结构至少包含两个分支。为了简化问题,循环结构视为具有进入循环体和不进入循环体两个分支,不考虑循环的次数。
比较常用的选择结构有IF结构,如C/C++/Java的if(…)…/else…;Pascal的if…then…else…;Basic的IF…THEN…END IF;该结构可含或不含ELSE分支,ELSE分支之前可增加不限数量的ELSE IF分支。
SWITCH结构,如C/C++/Java的switch(…)…,Pascal的case…of…,Basic的SELECT CASE…,该结构可含多个CASE分支,可含也可不含DEFAULT分支。
比较常用的循环结构有FOR结构如C/C++/Java的for(…)…,Pascal的for…do…,Basic的FOR…NEXT和FOR EACH…NEXT。
WHILE结构如C/C++/Java的while(…)…,Pascal的while…do…,Basic的DO WHILE…LOOP,DO UNTIL…LOOP。
Do…WHILE结构如C/C++/Java的do…while(…),Basic的DO…LOOPWHILE…,DO…LOOP UNTIL…,该结构至少执行循环体一次。
上述分支结构和编程语言的示例并非穷举,凡具有两个或两个以上执行路线的代码结构,都视为分支结构。
如上所述,循环结构视为具有进入循环体和不进入循环体两个分支,不考虑循环的次数,而Do…WHILE循环结构至少执行循环体一次,因此,它的不进入循环体的分支是不可达的。
分支结构也具有一个入口点和一个出口点,不论其内部的执行路线如何,在不发生异常的前提下,总是由入口点进入该结构,并由出口点离开该结构,这里有一个特例,如果结构内含有返回语句,执行到该语句时函数即返回,而不会从出口点离开该分支结构。
有些分支结构的某些分支是隐含的,如IF结构,如果最后没有ELSE分支,则包含一个隐含的分支,即使含有ELSE IF分支也是如此,此隐含的分支的执行条件和路线是当IF和所有ELSE IF判定均为假时,直接跳转到结构的出口点。含有隐含分支的情况还有循环结构的不进入循环体分支,该分支的执行条件和线路是第一次进行循环条件判断时,该条件即为假,直接跳转到结构的出口点;SWITCH结构,当不含DEFAULT分支时,也含有一个隐含的分支,其执行条件和路线是所有CASE分支的条件均不满足,不执行任一CASE分支,直接跳转到结构的出口点。
由于每一分支结构至少包含两条分支,可以说,分支结构是由分支构成的。分支包含两方面内容分支判定和分支体,分支判定的计算结果一般只有真和假两个值。判定为真时,执行分支体,否则不执行分支体。隐含分支的分支判定和分支体都是空的。对于某一分支来说,其分支体具有一定的范围,称为作用域,一般使用特定的符号来定义作用域的开始和结束,例如C/C++用花括号({}),PASCAL用begin和end来指定作用域的开始和结束。作用域内的所有语句,不论其结构如何,数量多少,均属于该分支体,因此,一个分支的分支体可以包含一个或多个顺序结构,也可以包含一个或多个分支结构,我们称为子结构,子结构又可以包含自己的子结构。
综上所述,本实施例把程序逻辑结构分为分支结构和顺序结构,一个分支结构至少包含两个分支,每一分支又可以进一步包含顺序结构和/或分支结构,我们把这种包含称为嵌套,嵌套的层次和数量没有限制。分支结构和顺序结构均有一个入口点和一个出口点,程序执行到任一结构时,在未发生异常的情况下,总是从入口点进入该结构,从出口点离开该结构,除非因执行到返回语句而提前返回。
本实施例用结构对象来对应描述上述程序逻辑结构用分支树对象描述分支结构,用分支对象描述分支结构中的一个分支,用语句块对象描述顺序结构。其中,分支树对象嵌套至少两个分支对象,分支对象可以嵌套任意数量的分支树对象和/或语句块对象,嵌套的层次和数量没有限制,语句块对象不嵌套其他对象。另外,本实施例把待示出逻辑结构的目标程序的整体视为一个分支,称为顶层分支,用一个顶层分支对象来描述,该顶层分支对象与其他分支对象不同的是,它不嵌套于其他对象。后文所述“分支对象”,包括顶层分支对象和其他层次的分支对象。我们把分支树对象、分支对象、语句块对象统称为结构对象。
如果对象A嵌套了对象B,我们把对象A称为对象B的父对象,对象B称为对象A的子对象。顶层分支对象没有父对象,语句块对象没有子对象,另外,分支对象也可能没有子对象。从对象的内部数据的关系来说,对象A(父对象)嵌套对象B(子对象),是指对象A保存了对象B本身或对象A保存了对象B的指针或引用,或对象A保存了可以引用到对象B的其他数据,通过对象A可以引用对象B;从对象的图示来说,对象A(父对象)嵌套对象B(子对象),是指对象B至少在一个方向上位于对象A的范围之内。
图7是在本实施例,各结构对象的内部数据构成示意图及结构对象树示意图,其中图7A是语句块对象的内部数据构成示意图,图7B是分支树对象的内部数据构成示意图,图7C是分支对象的内部数据构成示意图,图7A到图7C中,实线示出的是固定的组成部分,点划线示出的是可有可无并且不限数量的组成部分,图7D是结构对象树示意图,所对应的程序代码如图1A所示。
图7A是语句块对象的内部数据构成示意图,如图7A所示,语句块对象有一个代码字段,用于储存它所对应的程序代码,并有一个名称字段,用于识别不同的语句块对象,名称可以使用字母表示,如‘a’、‘b’、‘c’。
图7B是分支树对象的内部数据构成示意图,如图7B所示,分支树对象至少嵌套了两个分支对象,还可以嵌套更多的分支对象。分支结构中的每一分支实际上是该分支结构的不可分割的组成部分,没有这些分支,分支结构也就不存在,将分支独立出来作为一个对象来处理,仅是为了描述和实施上的简便,同时也更符合面向对象的思想。
图7C是分支对象的内部数据构成示意图,如图7C所示,分支对象有一个分支判定字段用于保存它对应的分支判定,顶层分支没有对应的分支判定,因此该字段为空。分支对象可以嵌套任意数量的分支树对象和/或语句块对象,如果没有嵌套分支树对象和语句块对象,则该分支对象称为空分支对象,与语句块对象一样,分支对象还具有一个名称字段,用于识别不同的分支对象,名称可以使用字母表示,如‘a’、‘b’、‘c’。
图7D是结构对象树示意图,对应于图1所示的代码。如图7D所示,描述一个程序的逻辑结构的所有结构对象构成了树状关系,我们称为结构对象树。
为了遍历上述每一结构对象,可对上述结构对象树进行后序扫描或前序扫描,后序扫描是指从顶层分支对象开始计算,针对每一对象,先递归计算它的每一个子对象,子对象计算完成后,再计算该对象自身,由于语句块对象和空分支对象没有子对象,计算它们时直接计算自身,因此它们是递归终止条件。前序扫描与后序扫描相比,唯一区别在于,针对每一对象,前序扫描先计算该对象自身,再递归计算子对象。
结构对象除具有内部数据构成外,还具有相应的外部表示,即显示在计算机屏幕或其他可视媒体上的图示,这些图示的组合就构成了程序的逻辑结构图。
图8是在本实施例,上述结构对象的图示的示意图。这些图示仅是为了便于描述和理解本发明,其形状、文字、颜色或其他组成部分并不表示对本发明权利要求或实施方式的限定,实施本发明时可以视需要修改这些图示的形状、文字、颜色或其他组成部分。
图8A是分支对象的图示的示意图,如图8A所示,811是分支的执行路线,可以在这条线上添加分支树对象和/或语句块对象,分支对象的入口点812和出口点813位于执行路线的两端。顶层分支对象的入口点就是程序的入口点,顶层分支对象的出口点就是程序的出口点。
图8B是分支对象的另一种图示的示意图,在图8A的基础上增加了分支标注。如图8B所示,822是分支标注,823是分支标注的文字。分支标注用于显示分支判定或其他说明文字,分支标注的宽度与分支的宽度相同或稍短,从分支标注可以看出分支的范围,因此分支标注的另一个作用是示出分支的范围。本实施例将分支判定作为分支标注的文字,其语法是C或C++的语法,不同编程语言可使用相应的语法。分支对象一般不单独存在,而是作为某一分支树对象的组成部分,如图8C。
图8C是分支树对象的图示的示意图,如图8C所示,831是入口线,832是出口线。每个分支树对象至少包含两个分支对象,这些分支对象是分支树对象的组成部分,虚线框833和虚线框834所标示的就是该分支树对象嵌套的两个分支对象。程序的执行线路是由入口线进入,执行某一分支,到达出口线并离开该分支树对象。图8D示出了分支树对象的入口点和出口点,入口点835和出口点836分别位于入口线的中点和出口线的中点。
图8E、图8F、图8G、图8H均是分支树对象的图示的示意图,由于分支结构有多种,不同种类的分支结构具有不同数量的分支,分支判定也不同,本实施例将分支树对象进一步细化,根据编程所用的语言,为各语言的每种常用的分支结构提供一个相应的分支树对象,例如,可为C++提供for、while、if、if/else、if/else if/else、switch等分支树对象(分别称为“for分支树”,“while分支树”、“if分支树”、“if/else分支树”、“if/else if/else分支树”、“switch分支树”等)。各种细化的分支树对象仅在分支数量和各分支的分支判定上有所区别,但对应于SWITCH结构的分支树还有外围代码,如C++的SWITCH结构的外围代码是switch(…){…}。本实施例为对应于SWITCH结构的分支树增加一个保存外围代码的字段,称为外围代码字段,用于保存类似于switch(…)的外围代码,但不保存作用域开始符和结束符,我们把对应于SWITCH结构的分支树称为特殊分支树。
图8I是语句块对象的图示的示意图,如图8I所示,843是语句块对象的范围矩形,语句块对象的入口点841和出口点842位于左右方向的中线与范围矩形的左右两端竖线的交点。
下面对图6所示的各步骤作进一步详细描述。
如图6所示,步骤A生成一个顶层分支对象,这是最顶层的对象,其他步骤所产生的对象均直接或间接嵌套于顶层分支对象中。
如图6所示,步骤B在任意层次的分支对象中嵌套分支树对象和/或语句块对象。首先,可以视需要在顶层分支对象中嵌套分支树对象和/或语句块对象,由于每一分支树对象至少含有两个分支对象,因此,就产生了其他层次的分支对象,这些分支对象可以进一步嵌套分支树对象和/或分支对象。
本发明可用于设计程序逻辑结构图(例如用于详细设计),也可用于根据已有的程序生成逻辑结构图(例如用于测试阶段)。本实施例用于设计程序逻辑结构图,步骤B所述的分支树对象和语句块对象由用户指定,嵌套分支树对象和/或语句块对象的分支对象也由用户指定,也就是说,用户选择分支树对象或语句块对象,并嵌套到合适的分支对象上,即可“堆砌”出程序逻辑结构图,所选对象的数量和嵌套的层次没有限制。下面用进行详细设计时,画出程序逻辑结构图的过程的示例来详细说明本实施例的步骤B图9是进行详细设计时,画出程序逻辑结构图的过程的示意图,图9A至图9D示出了画出对应于图1B所示代码的逻辑结构图的各步骤,均由两部分组成左边或上边是逻辑结构图的外部表示,右边或下边是相关对象的内部数据及其嵌套关系,所述的“重画”是指执行步骤C,后文将对步骤C作进一步详细描述。
为了便于用户选择对象,本实施例还提供一个对象选择界面,该界面可以切换编程语言,每种语言显示对应于各种分支结构的图标(即细化的分支树对象)以及对应于顺序结构的图标(即语句块对象)供用户选择。为了描述方便,当用户选择一个对应于某一分支结构的图标时,我们称为选择一个某种分支树,例如while分支树、if/else分支树,当用户选择一个对应于顺序结构的图标时,我们称为选择一个语句块,将这些选择统称为选择一个对象。
如图9A所示,用户选择while分支树并在顶层分支对象的图示上单击,该while分支树对应于图1B中虚线框101所示的代码。901是顶层对象的内部数据示意图,在顶层分支对象的内部数据901中嵌套while分支树对象902并重画,就得到图9B左边所示的逻辑结构图。
如图9B所示,用户选择语句块对象,并在顶层分支对象执行路线位于while分支树的右边单击,该语句块对应于图1B中虚线框105所示的代码。在顶层分支对象的内部数据中while对象之后嵌套一个语句块对象903并重画,得到图9C左边所示的逻辑结构图。
如图9C所示,用户选择if/else分支树,并在while分支树的第一分支单击,该if/else分支树对应于图1B中虚线框102所示的代码。在while分支树的第一分支对象的内部数据中嵌套一个if/else分支树对象904并重画,得到图9D上边所示的逻辑结构图。
如图9D所示,用户选择语句块对象,并分别在if/else分支树的第一分支和第二分支单击。在if/else分支树的第一分支对象和第二分支对象的内部数据中分别嵌套一个语句块对象905、906并重画,得到最终的逻辑结构图。语句块对象905对应于图1B中虚线框103所示的代码,语句块对象906对应于图1B中虚线框104所示的代码。
本实施例分别使用一个自动递增的字母变量来作为语句块对象和分支对象的名称,如‘a’、‘b’、‘c’。添加语句块对象时为该语句块对象命名,添加分支树对象时为其所属分支对象命名。
如图6所示,步骤C计算各对象的尺寸及位置并画出其图示,后文所述“重画”或“重画逻辑结构图”均是指重复执行步骤C。步骤C包括三个方面计算各对象的尺寸,本实施例使用宽度和高度来表示各对象的尺寸,由于分支树入口线高度的计算较复杂,因此,本实施例还把入口线高度也作为分支树对象的尺寸;计算各对象的位置,本实施例用入口点坐标来表示各对象的位置;画出各对象的图示。
由于子对象嵌套于父对象内,其范围位于父对象的范围之内,因此,增加或删除一个对象时,其直接或间接父对象的尺寸会发生变化,一些对象的位置也会发生变化,所以,增加或删除一个对象时,一般都需要重新计算各对象的相关尺寸和位置。为了计算各对象的相关尺寸和位置,还需预先定义一些基本尺寸。
图10是在本实施例,各对象的尺寸、位置和基本尺寸的示意图。
对象的宽度和高度就是对象(包括该对象的子对象)最上、最左、最右、最下位置连成的矩形(称为范围矩形)的宽度和高度。如图10所示,虚线画出的矩形1001是顶层分支对象的范围矩形,虚线画出的矩形1002是if/else分支树的范围矩形,虚线画出的矩形1003是while分支树的第一分支的范围矩形,虚线画出的矩形1004是if/else分支树的第一分支的范围矩形,实线画出的矩形1005是一个语句块对象的范围矩形。
如图10所示,E1是while分支树对象的入口线高度,E2是if/else分支树对象的入口线高度。
如图10所示,1011是顶层分支对象的入口点、1012是while分支树对象的入口点、1013是while分支树对象的第一分支的入口点、1014是语句块对象的入口点,它们的坐标就是相应对象的入口点坐标。
如图10所示,图10中由字母S开头的标注均表示基本尺寸,包括语句块对象的宽度S1、语句块对象的高度S2;分支标注的高度S3、分支标注与分支的距离S4、两条分支之间的距离S5;其中,分支标注并非必需的,如果省略分支标注,可以把S3和S4均设为0,不须改变后文所述的计算公式;左右方向连接的两个对象之间的距离S6。
基本尺寸不随对象的增删而变化,但可以通过调整基本尺寸来缩放逻辑结构图。
下面进一步详细描述步骤C。
C1.计算各对象的尺寸。如前所述,各对象的尺寸包括各对象的宽度和高度,计算各对象的宽度和高度的步骤是从顶层分支对象开始,针对每一对象,先递归计算各子对象的宽度和高度,再根据子对象的宽度和高度计算该对象的宽度和高度。
图11是本实施例计算各对象的宽度和高度的流程示意图,其中图11A是计算语句块对象的宽度和高度的流程示意图,图11B是计算分支对象的宽度和高度的流程示意图,图11C是计算分支树对象的宽度和高度的流程示意图。
如图11A所示,针对语句块对象,依下述公式计算其宽度和高度宽度=S1;高度=S2;其中,S1为语句块对象的宽度,S2为语句块对象的高度。
针对分支对象,依下述公式计算其宽度和高度宽度=S1+2*S6 (N=0);宽度=∑W+(N+1)*S6(N>0);高度=S3+S4 (N=0);高度=Hm+S3+S4(N>0);其中,N为该分支对象的子对象数量,S1为语句块对象的宽度,S6为左右方向连接的两个对象之间的距离,∑W为所有子对象的宽度之和,S3为分支标注的高度,S4为分支标注与分支的距离,Hm为高度最大的子对象的高度。
具体计算过程如图11B所示,如果子对象数量N为0,则用公式宽度=S1+2*S6,高度=S3+S4计算自身的宽度和高度,否则扫描子对象,如果子对象是语句块对象,则递归执行图11A所示的计算,否则递归执行图11C所示的计算;所有子对象计算完成后,查找高度最大的子对象,然后按公式宽度=∑W+(N+1)*S6,高度=Hm+S3+S4计算自身的宽度和高度。
针对分支树对象,依下述公式计算其宽度和高度宽度=Wm;高度=∑H+(N-1)*S5;其中,Wm为宽度最大的子对象的宽度,∑H为所有子对象的高度之和,N为子对象数量,S5为两条分支之间的距离。
具体计算过程如图11C所示,扫描子对象,针对每一子对象(子对象都是分支对象),递归执行图11B所示的计算,完成后查找宽度最大的分支,然后按上述的公式计算自身的宽度和高度。
计算完分支树的宽度和高度后,还要对齐分支,使分支树的所有分支的宽度相等,方法是修改除宽度最大的分支以外的各分支的宽度,令其等于宽度最大的分支的宽度。
如前所述,各对象的尺寸还可以进一步包括分支树对象的入口线高度,下面描述计算分支树对象的入口线高度的步骤。
为了计算分支树对象的入口线高度,需要先计算各对象的底座高度。所述底座高度就是对象的从入口点到范围矩形底边的距离,各对象均有自己的底座高度,底座高度也是计算入口点坐标的基础。用后序扫描方法计算各对象的底座高度,即从顶层分支对象开始,针对每一对象,先递归计算各子对象的底座高度,再根据各子对象的底座高度计算该对象的底座高度。
图12是本实施例计算各对象底座高度及分支树对象入口线高度的流程示意图,其中图12A是计算语句块对象底座高度的流程示意图,图12B是计算分支对象底座高度的流程示意图,图12C是计算分支树对象底座高度的流程示意图,图12D是计算分支树对象的入口线高度的流程示意图。
如图12A所示,针对语句块对象,依下列公式计算其底座高度底座高度=S2/2;其中S2为语句块对象的高度。
针对分支对象,依下述公式计算其底座高度底座高度=0 (N=0);底座高度=Bm(N>0);其中,N为子对象数量,Bm为底座高度最大的子对象的底座高度。
具体计算过程如图12B所示,如果子对象数量N为0,则按上述第一个公式计算底座高度,否则扫描子对象,如果子对象是语句块,则递归执行图12A所示的计算,否则递归执行图12C所示的计算,全部子对象计算完成后,查找底座高度最大的子对象,并按上述第二个公式计算底座高度。
针对分支树对象,依下述公式计算其底座高度底座高度=[B1+(Hn-Bn)+∑(H2…Hn-1)+(N-1)*S5]/2+Bn;其中,B1为第一子对象底座高度,Hn为最末子对象高度,Bn为最末子对象底座高度,∑(H2…Hn-1)为除第一子对象和最末子对象以外的其他子对象的高度之和,N为子对象数量,S5为两条分支之间的距离。
具体计算过程如图12C所示,扫描子对象,针对每一子对象,递归执行图12B所示的计算,所有子对象计算完成后,使用上述公式计算自身的底座高度。
如图12D所示,依下述公式计算分支树对象入口线高度入口线高度=B1+(Hn-Bn)+∑(H2…Hn-1)+(N-1)*S5;其中,B1为第一子对象底座高度,Hn为最末子对象高度,Bn为最末子对象底座高度,∑(H2…Hn-1)为除第一子对象和最末子对象以外的其他子对象的高度之和,N为子对象数量,S5为两条分支之间的距离。
C2.计算各对象的位置。如前所述,各对象的位置包括各对象入口点坐标。计算各对象入口点坐标的步骤如下从顶层分支对象开始,针对每一对象,先计算该对象的入口点坐标,再根据该对象的位置递归计算各子对象的入口点坐标。
为了便于描述和实施,本实施例采用如下坐标系横坐标向右为正,纵坐标向下为正,原点为顶层分支对象范围矩形的左上角。
针对顶层分支对象,依下述公式计算其入口点坐标X=0;Y=H-B;其中,X为入口点横坐标,向右为正,Y为入口点纵坐标,向下为正,H为对象高度,B为对象底座高度。
针对分支对象的第N个子对象,依下述公式计算其入口点坐标Xn=∑(W1…Wn-1)+N*S6;Yn=Yi;其中,N为从1开始的子对象顺序号,Xn为该第N个子对象的入口点的横坐标,向右为正,∑(W1…Wn-1)为该第N个子对象之前的子对象的宽度之和,S6为左右方向连接的两个对象之间的距离,Yn为所述第N个子对象的入口点的纵坐标,向下为正,Yi为分支对象入口点纵坐标。
针对分支树对象的第N个子对象,依下述公式计算其入口点坐标Xn=Xi;Yn=Yi-E/2(N=1);
Yn=Yn-1+Bn-1+Hn-Bn+S5(N>1);其中,N为从1开始的子对象顺序号,Xn为该第N个子对象的入口点的横坐标,向右为正,Xi为该分支树对象入口点横坐标,Yn为该第N个子对象的入口点的纵坐标,向下为正,Yn-1为前一子对象入口点纵坐标,Bn-1为前一子对象的底座高度,Hn为该第N个子对象的高度,Bn为该第N个子对象的底座高度,S5为两条分支之间的距离。
C3.画出各对象的图示。画出各对象图示的步骤如下从顶层分支对象开始,针对每一对象,先画出该对象的图示,再递归画出各子对象的图示。
画顶层分支对象前擦除旧的整幅图,画其他某一对象前擦除该对象范围矩形内的图形。
各对象均有出口点,其坐标(Xo,Yo)的为Xo=Xi+W;Yo=Yi;其中,Xi为入口点横坐标,W为对象的宽度,Yi为入口点纵坐标。
图13是本实施例画出各对象图示的示意图,其中图13A是画出分支对象图示的示意图,图13B是画出另一种分支对象图示的示意图,增加了分支标注,图13C是画出分支树对象图示的示意图,图13D是画出语句块对象图示的示意图。
如图13A所示,分支对象的图示包括执行线811。画出执行线811的方法是在入口点1311和出口点1312之间画一条线段。
如图13B所示,另一种分支对象的图示还包括分支标注822和分支标注的文字823。
除画出执行线外,还要画出分支标注,本实施例用矩形作为分支标注,画出分支标注的步骤如下计算分支标注矩形823,其左上角1321坐标(X,Y)为X=Xi+S6;Y=Yi+H-B+S3+S4;其中,Xi为该分支的入口点横坐标,S6为左右方向连接的两个对象之间的距离,Yi为该分支的入口点纵坐标,H为该分支高度,B为该分支底座高度,S3为分支标注的高度,S4为分支标注与分支的距离。
分支标注矩形的宽度和高度为
宽度=W-S6*2;高度=S3;其中,W为分支宽度,S6为左右方向连接的两个对象之间的距离,S3为分支标注的高度。
在本实施例,分支标注不画边框,只画出灰色背景。
最后在分支标注矩形中输出分支标注的文字。
如图13C所示,分支树对象的图示包括入口线831和出口线832,画法是计算入口线831的两个端点的坐标值(X1,Y1),(X2,Y2)X1=X2=Xi;其中Xi为入口点横坐标Y1=Yi-E/2;其中Yi为入口点纵坐标,E为入口线高度;Y2=Y1+E;其中Y1为入口线的上端点纵坐标,E为入口线高度。
将入口线向右偏移该分支树对象的宽度,即可得到出口线832,其坐标为(X1+W,Y1),(X2+W,Y2);其中W为分支树对象的宽度。
在(X1,Y1),(X2,Y2)之间画一条线段,即为入口线831。
在(X1+W,Y1),(X2+W,Y2)之间画一条线段,即为出口线832。
如图13D所示,本实施例用范围矩作为语句块的图示。画出语句块对象的图示的方法是用直线画出范围矩形843,矩形的左上角1341坐标为X=Xi;Y=Yi-S2/2;其中,Xi为该语句块入口点横坐标,Yi为该语句块入口点纵坐标,S2为语句块对象的高度。
各对象画出后,所获得的图形就是程序逻辑结构图,为了编辑和操作逻辑结构图,本实施例还可以增加下述步骤用于在分支树对象中添加分支的步骤,该步骤具体包括1)使用命中测试方法判断用户选择了哪个分支树对象;2)在该分支树对象中添加一个分支对象;3)重画逻辑结构图。
命中测试是指根据鼠标或光标的位置判断用户是否选中某一对象或鼠标在某一对象上停留的方法。本实施例采用后序扫描方法进行命中测试从顶层分支对象开始,针对每一对象,先递归测试各子对象,再测试该对象,命中某一对象时结束测试,判断命中的方法是如果鼠标或光标位置位于该对象的范围矩形内则命中,否则未命中。
用于在分支树对象中删除选定分支的步骤,该步骤具体包括1)使用前述的命中测试方法判断用户选择了哪个分支对象;2)在父对象中删除相应的分支对象;3)重画逻辑结构图。
添加和删除分支时,要保证分支树对象的完整,一般来说,可以添加和删除的,只能是IF结构的ELSE IF分支或ELSE分支、SWITCH结构的CASE分支和DEFAULT分支,IF结构中,ELSE分支或空分支必有其一,SWITCH结构中,DEFAULT分支与空分支也必有其一。循环结构对应的分支树对象不能添加或删除分支。
用于修改分支判定的步骤,该步骤具体包括1)使用前述的命中测试方法判断用户选择了哪个分支对象;2)显示一个编辑框,其中显示现有的分支判定;3)用户在编辑框中修改分支判定;4)将新的分支判定保存到分支对象中。
用于编辑语句块对象的代码的步骤,该步骤具体包括1)使用前述的命中测试方法判断用户选择了哪个语句块对象;2)显示一个编辑框,如果语句块对象已有代码,在编辑框中显示现有的代码;3)用户在编辑框中填写代码或修改代码;4)将编辑过的代码保存到该语句块对象中。
用于隐藏对象和/或显示对象的步骤。对于内部逻辑较复杂的程序,它的逻辑结构图也将较复杂,为了突出重点,便于分析程序逻辑结构,或者为了压缩程序路径,可将逻辑结构图的部分内容隐藏。本实施例可以将任意对象隐藏,画出隐藏的对象时,可以忽略它,也可以画出一个替代图示。图14是对部分图示的改进及画出隐藏对象的图示的示意图,如图14所示,如果隐藏的对象是分支树或语句块,则画出一个小矩形1405(称为替代矩形),通过这个小矩形可以选中该对象,并恢复正常显示,如果隐藏的对象是分支,则画成一条虚线1406。隐藏某一对象时,其直接或间接子对象同时隐藏。该步骤具体包括各对象增加一个记录状态的字段,该字段的取值有“正常”和“隐藏”,缺省值为“正常”;要隐藏某一对象,将它的状态设为“隐藏”,并重画逻辑结构图。当计算分支树和语句块对象的宽度和高度时,检查它的状态,如果状态为“隐藏”,则其宽度和高度为替代矩形的宽度S10和高度S11,并且忽略子对象。计算分支对象的宽度和高度时,检查它的状态,如果状态为“隐藏”,忽略子对象,视为空分支对象来计算宽度和高度。画出对象时,对于分支树对象和语句块对象,如果状态为“隐藏”,则只画一个替代矩形,忽略子对象,对于分支对象,如果状态为“隐藏”,则只在入口点和出口点之间画一条虚线,但分支标注仍然画出,忽略子对象。
用于由逻辑结构图生成程序代码的步骤,该步骤具体包括从顶层分支对象开始,递归扫描各对象,针对语句块对象,直接输出它对应的代码,针对分支对象,如果是空分支则忽略,否则先输出分支判定和分支作用域开始符(如C++的“{”或PASCAL的“begin”),然后扫描每一子对象,最后输出分支作用域结束符(如C++的“}”或PASCAL的“end”)。针对分支树对象,如果该对象是第一实施例所述的特殊分支树,如C++的switch分支树,则先输出外围代码如switch(…)和作用域开始符如“{”,再扫描各子对象(各分支),最后输出作用域结束符如“}”;如果不是特殊分支树对象,直接扫描各子对象(各分支)。生成代码时可视需要添加换行符,另外,各对象均有嵌套层次,如顶层分支对象的层次为0,顶层分支对象的直接子对象的层次为1,如此类推,可以根据嵌套层次计算代码缩进并加入空格,以生成符合习惯排版格式的代码。
另外,部分图示还可以作一些改进。如图14所示,可在顶层分支对象的左端加上程序入口图示1401,其宽度和高度为S7,右端加上出口图示1402,其直径为S8。设定坐标系时将原点向右偏移S7,留出入口图示的位置。
如图14所示,还可将分支树对象的入口线改为矩形1403,称为入口矩形,增加入口矩形使逻辑结构图的构成更清晰,计算分支树对象的宽度时,加上入口矩形的宽度S9,在计算各分支的入口点坐标时也加上该矩形造成的横坐标的偏移,画出分支树对象时,将入口线画成入口矩形。
如图14所示,当一个语句块对象对应的代码含有返回语句,还可将该语句块对象的图示画成如1404所示,即在右端加一个直径为S10的圆形,表示这也是程序的一个出口。
如前一实施例所述,本发明可用于设计程序逻辑结构图(例如用于详细设计),也可用于根据已有的程序生成逻辑结构图(例如用于测试阶段)。本实施例根据已有的程序生成逻辑结构图,图6所示的步骤B所述分支树对象和/或语句块对象依据程序代码生成。在本实施例,步骤B具体包括解析程序代码的逻辑结构,依据程序代码的分支结构生成对应的分支树对象及对应的分支对象,依据程序代码的顺序结构生成对应的语句块对象,并将所述分支树对象和所述语句块对象嵌套于对应层次的分支对象中,进一步详细描述如下首先,将程序代码分解为代码片。所述代码片是指以结构特征来确定类别的代码单位,代码片类别有判定、域符号、语句块,域符号又分为域开始和域结束。判定是指含有判断或跳转或类似关键字、用于控制其作用域内的语句执行或不执行的代码片,例如C++的if(…)、else if(…)、else、while(…)、switch(…)、caseN;Basic的lF…、ELSE IF…、ELSE、DO WHILE…。判定必须完整,例如,C++的if(…)是一个完整的判定,不论括号内的条件有多长,都属于该判定的组成部分,不能分拆。域符号是定义判定的作用域的代码,域开始紧接着判定,用于指定判定的作用域的开始,域结束用于指定判定的作用域的结束,典型的域符号如C++的“{”与“}”,PASCAL的“begin”与“end”;语句块是指对应于前文所述的顺序结构的代码序列,其中不能含有判定。位于某一代码片内的注释可忽略也可作为该代码片的一部分,位于代码片外的注释可忽略也可归于其后的代码片。图1C是代码片分类示例,如图1C所示,代码111、113、115对应的代码片为判定;代码112和117对应的代码片为域符号,其中代码112对应的代码片为域开始,代码117对应的代码片为域结束;代码114、116、118对应的代码片为语句块。
本实施例使用包含代码内容、类别、附加类别三个字段的数据结构来存储代码片,代码片保存在如链表或数组之类的数据容器中。分解代码时,针对判定类代码片,应判断是不是属于特殊分支树,及判断是不是属于一个分支树的后续分支,可根据判定的关键字分辨是否属于特殊分支树,如C++代码的switch关键字;后续分支也可根据判定的关键字来辨识,如针对C++代码,如果是else关键字引出的判定或else if关键字引出的判定,则属于后续分支,如果一个判定类代码片属于特殊分支树或后续分支(两者不可能并列),则记录在附加类别中。
有时,域符号是省略的,如C++代码,当作用域只有一条语句时,域符号是可省略的,再如,Basic的IF…THEN…结构中,THEN后不换行,其作用域为同一行的THEN后的语句,THEN是域开始,域结束省略;IF…THEN…END IF结构中,THEN和END IF是域开始和域结束,而IF…THEN…ELSE IF…THEN…ELSE…END IF结构中,ELSE IF之前省略了域结束,ELSE之前也省略了域结束。代码分解时,每个判定之后应保证具有匹配的域开始和域结束,凡域符号省略的,应补上相应的域符号,其代码为空。
分解代码时还要考虑隐含分支,当IF结构缺少ELSE分支,SWITCH结构缺少DEFAULT分支时,以及视为分支结构的循环结构,均含有隐含分支。应为隐含分支加上三个代码片一个判定,一个域开始,一个域结束,它们的代码均为空。
不同的编程语言,代码分解依据的语法及关键字略有不同,具体分解过程可用编译技术中的词法分析和语法分析技术来实现,实现过程属于现有技术,在此不作详述。
完成代码分解后,进一步将代码片映射为结构对象。图15是本实施例将代码片映射为结构对象的流程示意图,如图15所示,1501是输入的父对象,流程中所生成的分支树对象和语句块对象均嵌套于父对象中,父对象只能是分支对象。1502是代码片队列,将代码片按代码的本来顺序,用先进先出的队列储存,称为代码片队列。后文所述的“弹出代码片”,是指从代码片队列中取出最前的一个代码片,并将该代码片从代码片队列中删除;后文所述“代码片”,当未作限定时,是指最新弹出的代码片;后文所述“压入临时队列”,是指将代码片保存到临时代码片队列的尾部。本实施例将图15所示的流程编写为一个递归调用的函数,用参数方式传递父对象和代码片队列,初始调用时,将步骤A生成的顶层分支对象作为父对象,代码片队列包含程序的所有代码片,当处理一个分支时,为了进一步处理分支体所对应的代码片,将该分支作为父对象,该分支的分支体对应的代码片保存在一个临时代码片队列中作为输入的代码片队列,进行递归调用。
步骤1503判断代码片队列是否为空,如果为空则结束,否则执行步骤1504,步骤1504弹出代码片,在步骤1505判断该代码片的类别,如类别为语句块,执行步骤1511,如类别为判定,执行步骤1521,如类别为域符号,由于此时不应该出现域符号,执行步骤1590,步骤1590报告错误并退出。
步骤1511生成一个语句块对象,并嵌套在父对象中,本实施例在生成语句块对象时使用一个自动递增的字符变量作为每一个语句块对象的名称,如‘a’、‘b’、‘c’。步骤1512保存代码,将代码片的代码内容拷贝到语句块对象的代码字段中,然后返回到步骤1503处理下一代码片。
步骤1521生成分支树对象,并嵌套到父对象中,在步骤1522中根据代码片的附加类别判断该分支树是否属于特殊分支树,如果是特殊分支树,执行步骤1531,否则执行步骤1541。步骤1531保存外围代码,将代码片的代码内容拷贝到特殊分支树对象的外围代码字段。步骤1532判断代码片队列是否为空,如果为空则执行步骤1590报错并退出,否则执行步骤1533弹出代码片,并在步骤1534判断该代码片的类别,如果类别为域开始,则返回执行步骤1532(忽略外围代码的域开始,步骤1572忽略外围代码的域结束),如果类别为判定则执行步骤1541,如果类别不是域开始也不是判定,则执行步骤1590报错并退出。
步骤1541生成一个分支对象,嵌套于步骤1521生成的分支树对象中,本实施例在生成分支对象时使用一个自动递增的字符变量作为每一个分支对象的名称,如‘a’、‘b’、‘c’。步骤1542保存分支判定,将代码片的代码内容拷贝到该分支对象的分支判定字段。步骤1543判断代码片队列是否为空,如果为空则执行步骤1590报错并退出,否则执行步骤1545弹出代码片,并在步骤1546判断该代码片的类别,如果类别是域开始,则执行步骤1547,否则执行步骤1590报错并退出。步骤1547生成一个用于判断域符号是否匹配的变量N并赋值为1,表示读到了一个域开始,步骤1551判断代码片队列是否为空,如果为空则执行步骤1590报错并退出,否则执行步骤1552弹出代码片,并在步骤1553中判断该代码片的类别,如果类别是域开始,则N加1,如果是域结束,则N减1,然后判断N的值是否为0,如果为0,表示对应的域结束已弹出,实现了域匹配,执行步骤1562,否则在步骤1554将代码片压入临时队列,并返回步骤1551循环处理下一代码片。步骤1562处理分支体代码,将步骤1541生成的分支对象作为父对象,临时队列作为代码片队列,进行递归调用,然后清空临时队列。
步骤1563判断队列是否为空,如果为空则结束,否则在步骤1571弹出代码片,并在步骤1572判断该代码片的类别,如果类别是域结束,则返回执行步骤1571,如果类别是判定,则执行步骤1573,否则返回执行步骤1505处理后续的代码片直到结束。步骤1573根据代码片的附属类别判断该代码片是否属于上一分支的后续分支,如是则执行步骤1541,否则表示当前的分支树已处理完毕,返回执行步骤1505处理后续的代码片直到结束。
上面详细描述了图6所示的步骤B的另一种实施过程。本实施例从程序代码生成逻辑结构图,可用于在编写代码时保持逻辑结构图与代码的同步,也可用于在测试时生成程序代码逻辑结构图。
下面详细描述用于统计程序路径的实施例,本实施在前述实施例的基础上,包括一个用于统计程序路径的步骤。统计路径时也可以不画出程序的逻辑结构图,即可以省略计算各结构对象的尺寸及位置并画出其图示的步骤。
路径是指程序的执行路线,本实施例所述的路径包括语句组合和/或分支组合,也就是说,用语句组合和/或分支组合来描述路径,一般情况下,用语句组合来识别路径,分支组合可用于统计路径所覆盖的分支。语句组合是指路径所执行的语句块的序列,由语句块名按路径的执行顺序组成;分支组合是指路径所经历的分支的序列,由分支名按路径的经历顺序组成;也就是说,语句组合记录路径执行的语句,分支组合记录路径经历的分支。我们把路径的语句组合中的语句称为路径的执行语句,把路径的分支组合中的分支称为路径的经历分支。另外,由于统计路径的需要,路径还分为两类正常和返回,类别为返回的路径经过了一个含有返回语句的语句块,因此提前结束;类别为正常的路径在程序结束时结束。统计路径时,路径的缺省类别为正常,当一条路径经过一个含有返回语句的语句块时,将该路径的类别设为返回,该路径即结束。
统计程序路径的步骤具体包括后序扫描前述结构对象,针对每一对象,将一个输入路径集作为初始数据进行路径统计,顶层分支对象的输入路径集只含一条空路径;针对语句块对象,在输入路径集的每条路径中记录该语句块名;针对分支对象,在输入路径集的每条路径中记录该分支名,前一子对象的输出路径集作为下一子对象的输入路径集;针对分支树对象,将输入路径集的拷贝作为每一子对象的输入路径集。下面描述上述步骤中递归计算各结构对象时统计路径的详细步骤图16是本实施例统计程序路径的流程示意图,其中,图16A是当对象为语句块时统计路径的流程示意图,图16B是当对象为分支时统计路径的流程示意图,图16C是当对象为分支树时统计路径的流程示意图。
图16A是当对象为语句块时统计路径的流程示意图。如图16A所示,步骤1603扫描路径集,即扫描输入路径集1601,针对每一条路径,在步骤1604判断它的类别,如果类别为返回,则返回到步骤1603处理下一条路径,否则在步骤1605判断该语句块对象的代码是否含有返回语句,如果是,则执行步骤1606将路径的类别设为返回再执行步骤1607,否则直接执行步骤1607,步骤1607记录语句名,即在路径的语句组合的最后添加该语句块名。所有路径处理完成后即得到输出路径集1602,输出路径集中的路径的数量与输入路径集一致。
图16B是当对象为分支时统计路径的流程示意图。当对象为分支时,依次计算该对象的子对象,前一子对象计算后的输出路径集,作为下一子对象的输入路径集,直到所有子对象计算完毕,最末子对象的输出路径集就是该分支对象的输出路径集。如图16B所示,步骤1611记录分支,即在输入路径集的每条路径的分支组合的最后添加该分支名。步骤1612扫描每一子对象,如果完毕或没有子对象则结束,否则执行步骤1613。步骤1613判断该子对象是不是语句块,如果是则执行步骤1614,否则执行步骤1615,步骤1614递归执行图16A所示的计算,并将计算后的路径集作为下一子对象的输入路径集;步骤1615递归执行图16C所示的计算,并将输出的路径集作为下一子对象的输入路径集。步骤1614和步骤1615执行后均返回到步骤1612处理下一子对象直到结束。
图16C是当对象为分支树时统计路径的流程示意图。如图16C所示,步骤1623剔除返回路径将输入路径集1621中类别为返回的路径拷贝到输出路径集1622中,并从输入路径集1621删除。步骤1624扫描子对象(分支),读取一个分支后,步骤1625将输入路径集拷贝一份作为该分支的输入路径集。步骤1626针对该分支递归执行图16B所示的计算,然后返回到步骤1624处理下一分支。所有分支计算完成后,步骤1627将各分支的输出路径集汇总到整个分支树对象的输出路径集1622中,计算结束。
顶层分支对象的输入路径集只含一个空路径,所述空路径是指语句组合和分支组合均为空的路径;顶层分支对象的输出路径集就是程序的路径集。路径集中的每条路径,均记录了该路径所执行的语句块对象序列和该路径所经历的分支对象序列。
图17是逻辑结构图示出程序路径的示意图。如图17A所示的逻辑结构图,有3条路径,其语句组合分别是ac、bc、c;如图17B所示的逻辑结构图,有6条路径,其语句组合分别是adc、bdc、dc、aec、bec、ec;如图17C所示的逻辑结构图,有8条路径,其语句组合分别是adc、bdc、fdc、gdc、aec、bec、fec、gec。
当程序较复杂时,路径的数量会很庞大,要设计测试用例覆盖所有路径是不现实的。可以将一些特定的代码所对应的对象隐藏,统计路径时,忽略隐藏的对象及其直接或间接子对象,以便压缩路径的数量。如果画出了逻辑结构图,可以由用户选择要隐藏的对象,否则可以隐藏嵌套层次太深的对象。
本实例还包括画出程序路径图示的步骤,一次画出一条程序路径的图示,该步骤具体包括画出路径经过各分支树对象时的图示。扫描路径所经历的的分支,针对每一分支,如果该分支有父对象,则父对象是分支树对象,本实施例用加粗的线段连接父对象的入口点和该分支的入口点,及父对象的出口点与该分支的出口点。
画出路径经过各分支对象时的图示。扫描路径所经历的的分支,针对每一分支,本实施例用加粗的线段连接该分支对象的入口点、各子对象、出口点,即连接入口点与第一子对象的入口点,第一子对象的出口点与第二子对象的入口点,……,最末子对象的出口点与该分支的出口点。
画出路径经过各语句块对象时的图示。扫描路径所经历的的语句,针对每一语句块,本实施例用斜线填充语句块对象的范围矩形表示路径经过了该语句块。
图17A和图17B示出了本实施例画出一条程序路径的效果,其中,图17A示出了路径bc,图17B示出了路径ec。
从上述各实施例可看出,本发明提出的程序逻辑结构图示方法,可快速进行详细设计,可在程序代码与逻辑结构图之间双向转换,可用以统计和示出程序路径。本发明提出的程序路径统计方法,可自动统计程序路径并画出路径的图示。
上述各实施例仅是本发明的较佳实施方式,仅用以说明发本明而非限制,对本发明进行修改、变形或者等同替换而不脱离本发明的精神和范围,均应涵盖于本发明的范围之内。
权利要求
1.一种程序逻辑结构图示方法,其特征在于,包括步骤A.生成一个顶层分支对象;B.在任意层次的分支对象中嵌套分支树对象和/或语句块对象;C.计算上述各对象的尺寸及位置并画出其图示。
2.根据权利要求1所述的程序逻辑结构图示方法,其特征在于,将程序逻辑结构分为顺序结构和分支结构;所述语句块对象用于描述顺序结构,所述分支树对象用于描述分支结构,所述分支对象用于描述顶层分支或分支结构的一个分支;每一所述分支树对象至少嵌套了两个分支对象。
3.根据权利要求1所述的程序逻辑结构图示方法,其特征在于,所述嵌套包括被嵌套的对象的范围至少在一个方向上落在嵌套它的对象的范围之内。
4.根据权利要求1所述的程序逻辑结构图示方法,其特征在于,用细化的分支树对象描述不同的分支结构。
5.根据权利要求1所述的程序逻辑结构图示方法,其特征在于,所述步骤B所述分支树对象和/或语句块对象由用户指定。
6.根据权利要求5所述的程序逻辑结构图示方法,其特征在于,嵌套所述分支树对象和/或语句块对象的分支对象由用户指定。
7.根据权利要求1所述的程序逻辑结构图示方法,其特征在于,所述步骤B所述分支树对象和/或语句块对象依据程序代码生成。
8.根据权利要求7所述的程序逻辑结构图示方法,其特征在于,所述步骤B具体包括解析程序代码的逻辑结构,依据程序代码的分支结构生成对应的分支树对象及对应的分支对象,依据程序代码的顺序结构生成对应的语句块对象,并将所述分支树对象和所述语句块对象嵌套于对应层次的分支对象中。
9.根据权利要求1至8任一权利要求所述的程序逻辑结构图示方法,其特征在于,所述各对象的尺寸包括各对象的宽度和高度。
10.根据权利要求9所述的程序逻辑结构图示方法,其特征在于,所述步骤C包括步骤C1.从顶层分支对象开始,针对每一对象,先递归计算各子对象的宽度和高度,再根据子对象的宽度和高度计算该对象的宽度和高度,进一步包括依下述公式计算语句块对象的宽度和高度宽度=S1;高度=S2;其中,S1为语句块对象的宽度,S2为语句块对象的高度;依下述公式计算分支对象的宽度和高度宽度=S1+2*S6 (N=0);宽度=∑W+(N+1)*S6 (N>0);高度=S3+S4(N=0);高度=Hm+S3+S4 (N>0);其中,N为该分支对象的子对象数量,S1为语句块对象的宽度,S6为左右方向连接的两个对象之间的距离,∑W为所有子对象的宽度之和,S3为分支标注的高度,S4为分支标注与分支的距离,Hm为高度最大的子对象的高度;依下述公式计算分支树对象的宽度和高度宽度=Wm;高度=∑H+(N-1)*S5;其中,Wm为最宽子对象的宽度,∑H为所有子对象的高度之和,N为子对象数量,S5为两条分支之间的距离。
11.根据权利要求10所述的程序逻辑结构图示方法,其特征在于,所述各对象的尺寸进一步包括各分支树对象的入口线高度。
12.根据权利要求11所述的程序逻辑结构图示方法,其特征在于,所述步骤C1进一步包括计算各对象的底座高度;依下述公式计算分支树对象入口线高度入口线高度=B1+(Hn-Bn)+∑(H2...Hn-1)+(N-1)*S5;其中,B1为第一子对象底座高度,Hn为最末子对象高度,Bn为最末子对象底座高度,∑(H2...Hn-1)为除第一子对象和最末子对象以外的其他子对象的高度之和,N为子对象数量,S5为两条分支之间的距离。
13.根据权利要求12所述的程序逻辑结构图示方法,其特征在于,所述计算各对象的底座高度具体包括从顶层分支对象开始,针对每一对象,先递归计算各子对象的底座高度,再根据各子对象的底座高度计算该对象的底座高度,进一步包括依下述公式计算语句块对象的底座高度底座高度=S2/2;其中S2为语句块对象的高度;依下述公式计算分支对象的底座高度底座高度=0(N=0);底座高度=Bm (N>0);其中,N为子对象数量,Bm为底座高度最大的子对象的底座高度;依下述公式计算分支树对象的底座高度底座高度=[B1+(Hn-Bn)+∑(H2...Hn-1)+(N-1)*S5]/2+Bn;其中,B1为第一子对象底座高度,Hn为最末子对象高度,Bn为最末子对象底座高度,∑(H2...Hn-1)为除第一子对象和最末子对象以外的其他子对象的高度之和,N为子对象数量,S5为两条分支之间的距离。
14.根据权利要求1至8任一权利要求所述的程序逻辑结构图示方法,其特征在于,所述各对象的位置包括各对象的入口点坐标。
15.根据权利要求14所述的程序逻辑结构图示方法,其特征在于,所述步骤C包括步骤C2.从顶层分支对象开始,针对每一对象,先计算该对象的入口点坐标,再根据该对象的位置递归计算各子对象的入口点坐标,进一步包括依下述公式计算顶层分支对象的入口点坐标X=0;Y=H-B;其中,X为入口点横坐标,向右为正,Y为入口点纵坐标,向下为正,H为对象高度,B为对象底座高度;依下述公式计算分支对象的第N个子对象的入口点坐标Xn=∑(W1...Wn-1)+N*S6;Yn=Yi;其中,N为从1开始的子对象顺序号,Xn为该第N个子对象的入口点的横坐标,向右为正,∑(W1...Wn-1)为该第N个子对象之前的子对象的宽度之和,S6为左右方向连接的两个对象之间的距离,Yn为所述第N个子对象的入口点的纵坐标,向下为正,Yi为分支对象入口点纵坐标;依下述公式计算分支树对象的第N个子对象的入口点坐标Xn=Xi;Yn=Yi-E/2 (N=1);Yn=Yn-1+Bn-1+Hn-Bn+S5 (N>1);其中,N为从1开始的子对象顺序号,Xn为该第N个子对象的入口点的横坐标,向右为正,Xi为该分支树对象入口点横坐标,Yn为该第N个子对象的入口点的纵坐标,向下为正,Yn-1为前一子对象入口点纵坐标,Bn-1为前一子对象的底座高度,Hn为该第N个子对象的高度,Bn为该第N个子对象的底座高度,S5为两条分支之间的距离。
16.根据权利要求1至8任一权利要求所述的程序逻辑结构图示方法,其特征在于,所述分支树对象的图示包括入口线和出口线。
17.根据权利要求1至8任一权利要求所述的程序逻辑结构图示方法,其特征在于,所述分支对象的图示包括执行线。
18.根据权利要求17所述的程序逻辑结构图示方法,其特征在于,所述分支对象的图示进一步包括分支标注。
19.根据权利要求18所述的程序逻辑结构图示方法,其特征在于,所述分支对象的图示进一步包括分支标注的文字。
20.根据权利要求1至8任一权利要求所述的程序逻辑结构图示方法,其特征在于,所述语句块对象的图示包括范围矩形。
21.根据权利要求1至8任一权利要求所述的程序逻辑结构图示方法,其特征在于,所述步骤C包括步骤C3.从顶层分支对象开始,针对每一对象,先画出该对象的图示,再递归画出各子对象的图示。
22.根据权利要求21所述的程序逻辑结构图示方法,其特征在于,所述步骤C3进一步包括忽略隐藏的对象或针对隐藏的对象,只画出替代图示。
23根据权利要求1至8任一权利要求所述的程序逻辑结构图示方法,其特征在于,进一步包括用于在分支树对象中添加分支的步骤。
24.根据权利要求1至8任一权利要求所述的程序逻辑结构图示方法,其特征在于,进一步包括用于在分支树对象中删除选定分支的步骤。
25.根据权利要求1至8任一权利要求所述的程序逻辑结构图示方法,其特征在于,进一步包括用于修改分支判定的步骤。
26.根据权利要求1至8任一权利要求所述的程序逻辑结构图示方法,其特征在于,进一步包括用于编辑语句块对象的代码的步骤。
27.根据权利要求1至8任一权利要求所述的程序逻辑结构图示方法,其特征在于,进一步包括用于隐藏对象和/或显示对象的步骤。
28.根据权利要求1至8任一权利要求所述的程序逻辑结构图示方法,其特征在于,进一步包括用于由逻辑结构图生成程序代码的步骤。
29.一种根据权利要求1所述的程序逻辑结构图示方法统计程序路径的方法,其特征在于,用统计程序路径的步骤代替所述步骤C。
30.根据权利要求29所述的统计程序路径的方法,其特征在于,所述程序路径包括语句组合和/或分支组合。
31.根据权利要求29所述的统计程序路径的方法,其特征在于,所述统计程序路径的步骤包括后序扫描所述各对象,针对每一对象,将一个输入路径集作为初始数据进行路径统计,顶层分支对象的输入路径集只含一条空路径。
32.根据权利要求31所述的统计程序路径的方法,其特征在于,所述统计程序路径的步骤进一步包括针对语句块对象,在输入路径集的每条路径中记录该语句块名;针对分支对象,前一子对象的输出路径集作为下一子对象的输入路径集;针对分支树对象,将输入路径集的拷贝作为每一子对象的输入路径集。
33.根据权利要求32所述的统计程序路径的方法,其特征在于,所述统计程序路径的步骤进一步包括针对分支对象,在输入路径集的每条路径中记录该分支名。
34.根据权利要求31至33任一权利要求所述的统计程序路径的方法,其特征在于,所述统计程序路径的步骤进一步包括当路径经过含有返回语句的语句块对象时,该路径即结束。
35.根据权利要求31至33任一权利要求所述的统计程序路径的方法,其特征在于,所述统计程序路径的步骤进一步包括忽略隐藏的对象及隐藏的对象的直接或间接子对象。
36.根据权利要求29所述的统计程序路径的方法,其特征在于,进一步包括权利要求1所述的步骤C。
37.根据权利要求36所述的统计程序路径的方法,其特征在于,进一步包括画出程序路径的步骤。
38.根据权利要求37所述的统计程序路径的方法,其特征在于,所述画出程序路径的步骤具体包括画出路径经过各分支树对象时的图示;画出路径经过各分支对象时的图示;画出路径经过各语句块对象时的图示。
全文摘要
本发明公开了一种程序逻辑结构图示方法,其技术方案包括步骤A.生成一个顶层分支对象;B.在任意层次的分支对象中嵌套分支树对象和/或语句块对象;C.计算上述各对象的尺寸及位置并画出其图示。本发明还公开了一种程序路径统计方法,其技术方案是用统计程序路径的步骤代替上述技术方案中的步骤C。本发明使用结构对象作为绘图单位,对象的尺寸和位置自动计算,可以快速画出程序逻辑结构图,该逻辑结构图可以直观表现程序的执行路径。本发明提出的程序路径统计方法,自动统计程序路径,依据统计结果即可设计路径覆盖测试用例。
文档编号G06F11/36GK1908893SQ200510036190
公开日2007年2月7日 申请日期2005年8月1日 优先权日2005年8月1日
发明者王彤 申请人:王彤
网友询问留言 已有0条留言
  • 还没有人留言评论。精彩留言会获得点赞!
1