工程学中的很多原理和打棒球一样。你不一定非常强壮才能打出全垒打,你只需要打在球的正中心。
有向图是许多覆盖准则的基础。边的初始节点有时被称为前驱节点,终止节点被称为后继节点,路径是一个节点序列。
测试路径: 一条长度可能为0的路径p,它起始于N0中的某个节点,终止于Nf中的某个节点。
在有些图中,所有的测试路径都起始于一个节点且终止于一个节点。这些图就被称为单入/单出图,或是SESE图。
测试路径的极小集合被定义为如果从这个集合中拿走任意的测试用例,这个集合便不能满足我们的准则。
图覆盖准则大概有两类。
第一类通常称为控制流覆盖准则,或者更加泛化的称为结构图覆盖准则。
第二类基于代表软件工件的图中所使用的数据流,被称为数据流覆盖准则。
在一个典型的情况下,满足测试需求可以通过访问一个特殊的节点或边或者游历一条特殊的路径来实现。
图覆盖: 给定一个图覆盖准则C所包含的测试需求集TR,当且仅当对于TR中的每个测试需求tr,测试路径集path(T)中都至少存一个测试路径p满足tr的时候,测试用例集T满足图G的覆盖准则C。
7.2.1 结构化的覆盖准则
节点覆盖: 对于图G中的每个可达的节点n,测试需求集TR包含谓词访问n。
节点覆盖: TR包含G中每个可达的节点。
节点覆盖: 当且仅当对于N中每个语法上可达的节点n,path(T)中都有一条路径访问n,那么测试用例集T在图G上能满足节点覆盖。
边覆盖: TR包含G中每个可达的长度小于等于1的路径。
对边覆盖: TR包含G中每个可达的长度小于等于2的路径。
有一个测试准则很有效,它要求软件从某个状态(即有限状态机的一个节点)开始,然后经历一些迁移(即边),最后终止于初始节点。
当一条路径中,没有任何一条节点出现超过一次(除了初始节点和终止节点相同的情况),则称这条路径为简单路径。
主路径: 有一条从ni到nj的路径,当且仅当这条路径是一条简单路径,而且它不是其他任何简单路径的子路径时,这条路径为主路径。
主路径覆盖: TR包含G中的每条主路径。
往返路径是一条长度非零且初始节点和终止节点相同的主路径。
简单往返路径: 对于G中所有可达的,且可以作为往返路径起点和终点的节点,TR包含至少一条往返路径。
完全往返路径: 对于G中所有可达的节点,TR包含所有的往返路径
如果一个图有自环的话,完全路径覆盖是无用的,因为这会产生无穷的路径,因而产生无穷的测试需求。
指定路径覆盖: TR包含一个测试路径集合S,其中S是一个参数。
7.2.2 游历、顺路和绕路
虽然简单路径要求不包含内部循环,但是我们并不要求游历简单路径的测试路径也必须保持同样的属性。
游历: 当且仅当子路径q是测试路径p的一条子路径时,那么p游历q。
顺路游历: 当且仅当子路径q中的每条边出现的顺序和在测试路径p中出现的顺序相同,那么p顺路游历q。
绕路游历: 当且仅当子路径q中的每个节点出现的顺序和在测试路径p中出现的顺序相同,那么p绕路q。
顺路游历是处理不可行测试需求的一种实用方法。
最大游历限度问题就是要在图中找到一个路径(可以经过任意节点,但每个节点只能经过一次),使得该路径经过所有边至少一次且长度最大。
7.2.3 数据流准则
数值的定义:当一个变量的值被存于内存时这个变量所处的位置(变量赋值,输入变量值时等)。
数值的使用:当获取一个变量的值时变量所处的位置。
数据流测试准则所依据的一条事实是:数据值由定义转移到使用。我们将这种转移称为定义使用对,在测试文献中也被称为定义-使用或定义使用关联。
数据流覆盖准则的三个最常用的准则的方法是使用非形式化的定义。
第一个准则要求每个定义到达至少一个使用,
第二个准则要求每个定义到达所有可能的使用,
第三个准则要求每个定义通过所有可能的定义使用路径来到达所有可能的使用。
全定义覆盖(All Definition Coverage):这是一个测试覆盖准则,要求程序中的每个定义(变量、函数等)至少被测试一次。换句话说,每一个定义都应该在至少一个测试用例中被引用或使用。
全使用覆盖(All Use Coverage):这是另一个测试覆盖准则,要求程序中的每个定义(变量、函数等)在至少一个测试用例中被使用。换句话说,每一个定义都应该在至少一个测试用例中被调用或执行。
全定义使用路径覆盖(All Definition Use Path Coverage):这是一个更高级的测试覆盖准则,要求程序中所有从定义到使用的路径都被至少一个测试用例覆盖。换句话说,每一个定义和它的每一个使用点之间的路径都应该在至少一个测试用例中被执行。
应用图准则的第一步是定义图,对于源代码而言,最通用的图称为控制流图
基于源代码的图覆盖是一种测试覆盖准则,它要求测试用例覆盖源代码中的所有语句、分支和数据流。这种覆盖准则的目标是确保源代码中的所有逻辑都被测试到,以便检测潜在的问题和错误。
基于源代码的图覆盖通常使用控制流图(Control Flow Graph,简称CFG)来表示源代码中的控制流程。CFG是一个有向图,其中每个节点代表源代码中的一个语句或控制流构造(例如if语句、循环等),每个边代表控制流的转移。基于源代码的图覆盖要求测试用例覆盖CFG中的所有节点和边。
此外,基于源代码的图覆盖还可以使用数据流图(Data Flow Graph,简称DFG)来表示源代码中的数据流。DFG是一个有向图,其中每个节点代表源代码中的一个语句或控制流构造,每个边代表数据的流动。基于源代码的图覆盖要求测试用例覆盖DFG中的所有节点和边。
基于源代码的图覆盖是一种相对较强的测试覆盖准则,可以检测出许多潜在的问题和错误。然而,实现这种覆盖准则可能需要更多的测试资源和时间,因为它需要覆盖源代码中的所有逻辑和数据流。因此,在实际应用中,需要根据测试需求和资源来平衡测试覆盖准则的强度和资源消耗。
数据抽象和面向对象软件的使用导致我们更多地关注模块化的重用。这意味着基于设计中各种部分(设计元素)的软件测试比过去变得更重要。
设计元素的图覆盖是一种在软件开发中使用的技术,它涉及使用设计元素(例如类、接口、函数等)的集合来构建软件系统的模型,并使用特定的覆盖准则来确定测试用例的数量和质量。
在这种模型中,设计元素之间的关系通常被表示为有向图,其中每个节点代表一个设计元素(例如类、接口、函数等),每个边代表一个依赖关系(例如一个类调用另一个类的方法、继承关系等)。
在这种图模型中,不同的覆盖准则可以应用于设计元素之间的连接,以确定测试用例的数量和质量。例如,类之间的调用图可以使用节点覆盖和边覆盖准则来确定测试用例的数量和质量。节点覆盖准则要求每个被调用的类至少被测试一次,而边覆盖准则要求每个类之间的调用关系至少被测试一次。
此外,继承图覆盖也可以应用于继承关系的测试中。在这种情况下,测试用例的数量和质量取决于继承关系的覆盖准则。例如,如果一个子类继承了多个父类,那么需要测试用例来覆盖所有父类的属性和方法。
总之,设计元素的图覆盖是一种有效的软件测试技术,它可以确定测试用例的数量和质量,以覆盖所有重要的设计元素和它们之间的关系。
设计规范的图覆盖是一种在软件开发中使用的技术,它涉及使用设计规范(例如面向对象设计原则、设计模式等)来指导软件系统的设计和实现,并使用特定的覆盖准则来确定测试用例的数量和质量。
在这种模型中,设计规范可以被表示为有向图,其中每个节点代表一个设计原则或模式,每个边代表一个依赖关系(例如一个类实现了一个接口、一个类继承了一个父类等)。
在这种图模型中,不同的覆盖准则可以应用于设计规范之间的连接,以确定测试用例的数量和质量。例如,接口覆盖准则可以应用于接口图,要求每个接口至少被实现一次,而继承覆盖准则可以应用于继承图,要求每个子类都继承了所有父类的属性和方法。
此外,设计规范的图覆盖还可以应用于分析现有代码的结构和质量。在这种情况下,可以使用特定的覆盖准则来分析代码,以确定代码的质量和符合设计规范的程度。例如,可以使用结构覆盖准则来分析代码中的类和函数,以确定它们是否符合面向对象的设计原则和模式。
总之,设计规范的图覆盖是一种有效的软件测试技术,它可以确定测试用例的数量和质量,以覆盖所有重要的设计规范和它们之间的关系。
用例的图覆盖是一种测试覆盖策略,它专注于使用设计元素(例如类、接口、函数等)的集合来构建软件系统的模型,并使用特定的覆盖准则来确定测试用例的数量和质量。
在这种模型中,测试用例可以被表示为有向图,其中每个节点代表一个测试用例,每个边代表一个依赖关系(例如一个测试用例依赖于另一个测试用例、一个测试用例包含多个场景等)。
在这种图模型中,不同的覆盖准则可以应用于测试用例之间的连接,以确定测试用例的数量和质量。例如,路径覆盖准则可以应用于测试用例图,要求每个路径都至少被测试一次,而场景覆盖准则可以应用于测试用例图,要求每个场景都至少被测试一次。
此外,用例的图覆盖还可以应用于分析现有测试用例的结构和质量。在这种情况下,可以使用特定的覆盖准则来分析测试用例,以确定它们的质量和覆盖范围。例如,可以使用结构覆盖准则来分析测试用例中的输入和输出,以确定它们是否覆盖了所有可能的场景和预期结果。
总之,用例的图覆盖是一种有效的软件测试技术,它可以确定测试用例的数量和质量,以覆盖所有重要的设计元素和它们之间的关系。