一、测试方法概述
二、逻辑覆盖
三、关于控制结构测试的一些讨论
四、基本路径测试
五、等价类划分
六、边界值分析
七、错误推测法
八、因果图
九、测试方法选择的综合策略
软件测试的种类大致可以分为人工测试和基于计算机的测试。而基于计算机的测试由可以分为白盒测试和黑盒测试。任何工程化的产品都有两种测试方法,一种方法是已知产品应该具有的功能,通过测检验每个功能是否正常使用,另一种方法是已知产品内部工作过程,通过测试检验产品内部动作是否按照产品规格说明的规定正常进行。前者称为黑盒测试,后者称为白盒测试。测试用例 和测试场景 将根据这两种测试方法的特性制定。
1.黑盒测试
根据软件产品的功能设计规格,在计算机上进行测试,以证实每个实现了的功能是否符合要求。这种测试方法就是黑盒测试。黑盒测试意味着测试要在软件的接口处进行。就是说,这种方法是把测试对象看做一个黑盒子,测试人员完全不考虑程序内部的逻辑结构和内部特性,只依据程序的需求分析规格说明,检查程序的功能是否符合它的功能说明。
用黑盒测试发现程序中的错误,必须在所有可能的输入条件和输出条件中确定测试数据,来检查程序是否都能产生正确的输出。
2.白盒测试
根据软件产品的内部工作过程,在计算机上进行测试,以证实每种内部操作是否符合设计规格要求,所有内部成分是否已经过检查。这种测试方法就是白盒测试。白盒测试把测试对象看做一个打开的盒子,允许测试人员利用程序内部的逻辑结构及有关信息,设计或选择测试用例,对程序所有逻辑路径进行测试。通过在不同点检查程序的状态,确定实际的状态是否与预期的状态一致。
不论是黑盒测试,还是白盒测试,都不可能把所有可能的输入数据都拿来进行所谓的穷举测试。因为可能的测试输入数据数目往往达到天文数字。下面让我们看两个例子。
假设一个程序P有输入X和Y及输出Z,参看图 10-4-1 。在字长为32位的计算机上运行。如果X 、Y只取整数,考虑把所有的X 、Y值都做为测试数据,按黑盒测试方法进行穷举测试,力图全面、无遗漏地“挖掘”出程序中的所有错误。这样做可能采用的测试数据组(Xi,Yi)的最大可能数目为: 。如果程序P测试一组X、Y数据需要 1毫秒,且一天工作24小时,一年工作365天,要完成264组测试,需要5亿年。
图 10-4-1 黑盒子
而对一个具有多重选择和循环嵌套的程序,不同的路径数目也可能是天文数字。设给出一个如图 10-4-2 所示的小程序的流程图,其中包括了一个执行达20次的循环。那么它所包含的不同执行路径数高达 条,若要对它进行穷举测试,覆盖所有的路径。假使测试程序对每一条路径进行测试需要1毫秒,同样假定一天工作24小时,一年工作365 天,那么要想把如图 10-4-2所示的小程序的所有路径测试完,则需要3170年。
图 10-4-2 白盒测试中的穷举测试
以上的分析表明,实行穷举测试,由于工作量过大,实施起来是不现实的。任何软件开发项目都要受到期限、费用、人力和机时等条件的限制,尽管为了充分揭露程序中所有隐藏错误,需要针对所有可能的数据进行测试,但事实告诉我们,这样做是不可能的。
软件工程的总目标是充分利用有限的人力、物力资源,高效率、高质量、低成本地完成软件开发项目。在测试阶段既然穷举测试不可行,为了节省时间和资源,提高测试效率,就必须要从数量极大的可用测试用例中精心地挑选少量的测试数据,使得采用这些测试数据能够达到最佳的测试效果,能够高效率地把隐藏的错误揭露出来。
逻辑覆盖是以程序内部的逻辑结构为基础的设计测试用例的技术。属白盒测试。这一方法要求测试人员对程序的逻辑结构有清楚的了解,甚至要能掌握源程序的所有细节。由于覆盖测试的目标不同,逻辑覆盖又可分为:语句覆盖、判定覆盖、判定-条件覆盖、条件组合覆盖及路径覆盖。
1.语句覆盖
语句覆盖就是设计若干个测试用例,运行被测程序,使得每一可执行语句至少执行一次。这种覆盖又称为点覆盖,它使得程序中每个可执行语句都得到执行,但它是最弱的逻辑覆盖准,效果有限,必须与其他方法交互使用。
2.判定覆盖
判定覆盖就是设计若干个测试用例,运行被测程序,使得程序中每个判断的取真分支和取假分支至少经历一次。判定覆盖又称为分支覆盖。
判定覆盖只比语句覆盖稍强一些,但实际效果表明,只是判定覆盖,还不能保证一定能查出在判断的条件中存在的错误。因此,还需要更强的逻辑覆盖准则去检验判断内部条件。
3.条件覆盖
条件覆盖就是设计若干个测试用例,运行被测程序,使得程序中每个判断的每个条件的可能取值至少执行一次。
条件覆盖深入到判定中的每个条件,但可能不能满足判定覆盖的要求。
4.判定-条件覆盖
判定-条件覆盖就是设计足够的测试用例,使得判断中每个条件的所有可能取值至少执行一次,同时每个判断本身的所有可能判断结果至少执行一次。换言之,即是要求各个判断的所有可能的条件取值组合至少执行一次。
判定-条件覆盖有缺陷。从表面上来看,它测试了所有条件的取值。但是事实并非如此。往往某些条件掩盖了另一些条件。会遗漏某些条件取值错误的情况。为彻底地检查所有条件的取值,需要将判定语句中给出的复合条件表达式进行分解,形成由多个基本判定嵌套的流程图。这样就可以有效地检查所有的条件是否正确了。
图 10-4-3 (a) 复合判定的例子
图 10-4-3 (b) 改为单个条件判定的嵌套结构的例子
5.多重条件覆盖
多重条件覆盖就是设计足够的测试用例,运行被测程序,使得每个判断的所有可能的条件取值组合至少执行一次。
这是一种相当强的覆盖准则,可以有效地检查各种可能的条件取值的组合是否正确。它不但可覆盖所有条件的可能取值的组合,还可覆盖所有判断的可取分支,但可能有的路径会遗漏掉。测试还不完全。
6.路径测试
路径测试就是设计足够的测试用例,覆盖程序中所有可能的路径。这是最强的覆盖准则。但在路径数目很大时,真正做到完全覆盖是很困难的,必须把覆盖路径数目压缩到一定限度。下面我们做一分析。
1.分支结构的路径数
当程序中判定多于一个时,形成的分支结构可以分为两类:嵌套型分支结构和连锁型分支结构。如图 10-4-4 所示。对于嵌套型分支结构,若有n个判定语句,则需要n+1个测试用例;但对连锁型分支结构,若有n个判定语句,则需要有 个测试用例,去覆盖它的 条路径。当n较大时将无法测试。
(a)嵌套型分支结构
(b)连锁型分支结构
图 10-4-4 分支的两种类型
为减少测试用例的数目,可采用试验设计法,抽取部分路径进行测试。由于抽样服从均匀分布,因此,在假定各条路径的重要性相同,或暂不明确各条路径的重要性的情况下可以做到均匀抽样。如果明确了各条路径的重要性,还可以采取加权的办法,筛选掉部分路径,再用如下的措施进行抽样。具体步骤如下:
(1) 设耦合型分支结构中有n个判定,计算满足关系式 的最小自然数m;
(2) 设 ,取正交表L4,并利用它设计测试数据。
例如,一个耦合型分支结构中有三个判定语句P1,P2,P3。它全部路径是23=8条。先计算 的t,得t= 4。取正交表L4,如图 10-4-5 (a)所示,把每一列当做一个判定,每一行当做可取的测试用例,则正交表L4最多可取三个判定,分别代之以P1,P2,P3。判定P1,P2,P3的取假分支和取真分支分别记作S1、S2;S3、S4;S5、S6,用各个判定的取假分支取代正交表L4中的“0”,用取真分支取代正交表中的“1”,就建立起一个测试路径矩阵,如图 10-4-5(b)所示。这样,测试路径数目从 条减少到3+1=4条。
图 10-4-5 (a) 正交表L4
图 10-4-5 (b) 路径抽样矩阵
2.条件测试的策略
程序中的条件分为简单条件和复合条件。简单条件是一个布尔变量或一个关系表达式(可加前缀NOT),复合条件由简单条件通过逻辑运算符(AND、OR、NOT)和括号连接而成。如果条件出错,至少是条件中某一成分有错。条件中可能的出错类型有:布尔运算符错、布尔变量错、布尔括号错、关系运算符错、算术表达式错。
如果在一个判定的复合条件表达式中每个布尔变量和关系运算符最多只出现一次,而且没有公共变量,应用一种称之为BRO(分支与关系运算符)的测试法可以发现多个布尔运算符或关系运算符错,以及其他错误。
BRO策略引入条件约束的概念。设有n个简单条件的复合条件C,其条件约束为 ,其中 是条件C中第i个简单条件的输出约束。如果在C的执行过程中,其每个简单条件的输出都满足D中对应的约束,则称条件C的条件约束D由C的执行所覆盖。特别地,布尔变量或布尔表达式的输出约束必须是真(t)或假(f);关系表达式的输出约束为符号>、=、<。
(1) 设条件为 。其中 是布尔变量, 的输出约束为 ,在此, 和 或为t或为f。则 是 可能的一个约束。覆盖此约束的测试(一次运行)将令 为t, 为f。BRO策略要求对 的可能约束集合 中的每一个,分别设计一组测试用例。如果布尔运算符有错,这三组测试用例的运行结果必有一组导致 失败。
(2) 设条件为 。其中 是布尔表达式, 和 是算术表达式, 的输出约束为 ,在此, 或为t或为f; 则是<、= 或>。因此,只有 与 中 的不同,可以修改 的约束集合 ,导出 的约束集合。因为在 中,“t”相当于“=”,“f”相当于“<”或“>”,则 的约束集合为 。据此设计4组测试用例,检查 中可能的布尔或关系运算符中的错误。
(3) 设条件为 。其中 都是算术表达式, 的输出约束为 ,在此, 和 的约束均为<、=、>。 中只有 与 中的 不同,可以修改 的约束集合 ,导出 的约束集合。因为在 中,“t” 相当于“>”,"f"相当于“<”或“=”,则 的约束集合为 。根据这个约束集合设计测试用例,就能够检测 中的关系运算符中的错误。
3.循环测试
循环分为4种不同类型:简单循环、连锁循环、嵌套循环和非结构循环,见图 10-4-6 。
图 10-4-6 循环的分类
对于简单循环,测试应包括以下几种,其中的n表示循环允许的最大次数。
(1) 零次循环:从循环入口直接跳到循环出口。
(2) 一次循环:查找循环初始值方面的错误。
(3) 二次循环:检查在多次循环时才能暴露的错误。
(4) m次循环:此时的m<n,也是检查在多次循环时才能暴露的错误。
·最大次数循环、比最大次数多一次的循环、比最大次数少一次的循环。
对于嵌套循环,不能将简单循环的测试方法简单地扩大到嵌套循环,因为可能的测试数目将随嵌套层次的增加呈几何倍数增长。这可能导致一个天文数字的测试数目。下面给出一种有助于减少测试数目的测试方法。
·除最内层循环外,从最内层循环开始,置所有其他层的循环为最小值;
·对最内层循环做简单循环的全部测试。测试时保持所有外层循环的循环变量为最小值。另外,对越界值和非法值做类似的测试。
·逐步外推,对其外面一层循环进行测试。测试时保持所有外层循环的循环变量取最小值,所有其它嵌套内层循环的循环变量取“典型”值。
·反复进行,直到所有各层循环测试完毕。
·对全部各层循环同时取最小循环次数,或者同时取最大循环次数。对于后一种测试,由于测试量太大,需人为指定最大循环次数。
对于连锁循环,要区别两种情况。如果各个循环互相独立,则连锁循环可以用与简单循环相同的方法进行测试。例如,有两个循环处于连锁状态,则前一个循环的循环变量的值就可以做为后一个循环的初值。但如果几个循环不是互相独立的,则需要使用测试嵌套循环的办法来处理。
对于非结构循环,应该使用结构化程序设计方法重新设计测试用例。
如果把覆盖的路径数压缩到一定限度内,例如,程序中的循环体只执行零次和一次,就成为基本路径测试。它是在程序控制流图的基础上,通过分析控制构造的环路复杂性,导出基本可执行路径集合,从而设计测试用例的方法。
设计出的测试用例要保证在测试中,程序的每一个可执行语句至少要执行一次。
1.程序的控制流图
控制流图是描述程序控制流的一种图示方法。基本控制构造的图形符号如图 10-4-7 所示。符号○称为控制流图的一个结点,一组顺序处理框可以映射为一个单一的结点。控制流图中的箭头称为边,它表示了控制流的方向,在选择或多分支结构中分支的汇聚处,即使没有执行语句也应该有一个汇聚结点。边和结点圈定的区域叫做区域,当对区域计数时,图形外的区域也应记为一个区域。
图 10-4-7 控制流图的各种图形符号
如果判定中的条件表达式是复合条件时,即条件表达式是由一个或多个逻辑运算符(OR,AND,NAND,NOR)连接的逻辑表达式,则需要改复合条件的判定为一系列只有单个条件的嵌套的判定。例如对应图 10-4-8 (a)的复合条件的判定,应该画成如图 10-4-8(b)所示的控制流图。条件语句ifaORb中条件a和条件b各有一个只有单个条件的判定结点。
图 10-4-8 复合逻辑下的控制流图
2.计算程序环路复杂性
进行程序的基本路径测试时,程序的环路复杂性给出了程序基本路径集合中的独立路径条数,这是确保程序中每个可执行语句至少执行一次所必需的测试用例数目的上界。
所谓独立路径,是指包括一组以前没有处理的语句或条件的一条路径。如在图 10-4-9 (b)所示的控制流图中,一组独立的路径是
path1:1-11
path2: 1-2-3 -4-5-10-1-11
path3: 1-2-3 -6-8-9-10-1-11
path4: 1-2-3 -6-7-9-10-1-11
路径path1,path2,path3,path4组成了图 10-4-9 (b)所示控制流图的一个基本路径集。只要设计出的测试用例能够确保这些基本路径的执行,就可以使得程序中的每个可执行语句至少执行一次,每个条件的取真和取假分支也能得到测试。基本路径集不是唯一的,对于给定的控制流图,可以得到不同的基本路径集。
(a)程序流程图
(b)控制流图
图 10-4-9 程序流程图与对应的控制流图
通常环路复杂性可用以下3种方法求得。
(1) 将环路复杂性定义为控制流图中的区域数。
(2) 设E为控制流图的边数,N为图的结点数,则定义环路复杂性为V(G)=E-N+2。
(3) 若设P为控制流图中的判定结点数,则有V(G)=P+1。
因为图 10-4-9 (b)所示控制流图有4个区域。其环路复杂性为4。它是构成基本路径集的独立路径数的上界。可以据此得到应该设计的测试用例的数目。
3.导出测试用例
利用逻辑覆盖方法生成测试用例,确保基本路径集中每条路径的执行。
等价类划分是一种典型的黑盒测试方法。使用这一方法时,完全不考虑程序的内部结构,只依据程序的规格说明来设计测试用例。由于不可能用所有可以输入的数据来测试程序,而只能从全部可供输入的数据中选择一个子集进行测试。如何选择适当的子集,使其尽可能多地发现错误。解决的办法之一就是等价类划分。
首先把数目极多的输入数据(有效的和无效的)划分为若干等价类。所谓等价类是指某个输入域的子集合。在该子集合中,各个输入数据对于揭露程序中的错误都是等效的。并合理地假定:测试某等价类的代表值就等价于对这一类其他值的测试。因此,我们可以把全部输入数据合理划分为若干等价类,在每一个等价类中取一个数据做为测试的输入条件,就可用少量代表性测试数据,取得较好的测试效果。
1.等价类划分的2种情况
等价类的划分有2种不同的情况:
(1) 有效等价类:是指对于程序规格说明来说,是合理的,有意义的输入数据构成的集合。利用它,可以检验程序是否实现了规格说明预先规定的功能和性能。
(2) 无效等价类:是指对于程序规格说明来说,是不合理的,无意义的输入数据构成的集合。利用它,可以检查程序中功能和性能的实现是否有不符合规格说明要求的地方。
2.等价类划分的原则
在设计测试用例时,要同时考虑有效等价类和无效等价类的设计。软件不能都只接收合理的数据,还要经受意外的考验,接受无效的或不合理的数据,这样获得的软件才能具有较高的可靠性。划分等价类的原则如下:
(1) 按区间划分:如果可能的输入数据属于一个取值范围或值的个数限制范围,则可以确立一个有效等价类和两个无效等价类。
(2) 按数值划分:如果规定了输入数据的一组值,而且程序要对每个输入值分别进行处理。则可为每一个输入值确立一个有效等价类,此外针对这组值确立一个无效等价类,它是所有不允许的输入值的集合。
(3) 按数值集合划分:如果可能的输入数据属于一个值的集合,或者须满足“必须如何”的条件,这时可确立一个有效等价类和一个无效等价类。
(4) 按限制条件或规则划分:如果规定了输入数据必须遵守的规则或限制条件,则可以确立一个有效等价类(符合规则)和若干个无效等价类(从不同角度违反规则)。
3.确立测试用例
在确立了等价类之后,应建立等价类表,列出所有划分出的等价类:
再从划分出的等价类中按以下原则选择测试用例:
(1) 设计尽可能少的测试用例,覆盖所有的有效等价类;
(2) 针对每一个无效等价类,设计一个测试用例来覆盖它。
人们从长期的测试工作经验得知,大量的错误是发生在输入或输出范围的边界上,而不是在输入范围的内部。因此针对各种边界情况设计测试用例,可以查出更多的错误。
比如,在做三角形计算时,要输入三角形的三个边长:A、B和C。我们应注意到这三个数值应当满足A>0、B>0、C>0、A+B>C、A+C>B、B+C>A,才能构成三角形。但如果把六个不等式中的任何一个大于号“>”错写成大于等于号“≥”,那就不能构成三角形。问题恰出现在容易被疏忽的边界附近。这里所说的边界是指,相当于输入等价类和输出等价类而言,稍高于其边界值及稍低于其边界值的一些特定情况。
使用边界值分析方法设计测试用例,首先应确定边界情况。通常输入等价类与输出等价类的边界,就是应着重测试的边界情况。应当选取正好等于,刚刚大于,或刚刚小于边界的值做为测试数据,而不是选取等价类中的典型值或任意值做为测试数据。
边界值分析方法是最有效的黑盒测试方法,但当边界情况很复杂的时候,要找出适当的测试用例还需针对问题的输入域、输出域边界,耐心细致地逐个考虑。
人们也可以靠经验和直觉推测程序中可能存在的各种错误,从而有针对性地编写检查这些错误的例子。这就是错误推测法。
错误推测法的基本想法是:列举出程序中所有可能有的错误和容易发生错误的特殊情况,根据它们选择测试用例。例如,在介绍单元测试时曾列出许多在模块中常见的错误,这些是单元测试经验的总结。此外,对于在程序中容易出错的情况,也有一些经验总结出来。例如,输入数据为0,或输出数据为0是容易发生错误的情形,因此可选择输入数据为0,或使输出数据为0的例子作为测试用例。又例如,输入表格为空或输入表格只有一行,也是容易发生错误的情况。可选择表示这种情况的例子作为测试用例。再例如,可以针对一个排序程序,输入空的值(没有数据)、输入一个数据、让所有的输入数据都相等、让所有输入数据有序排列、让所有输入数据逆序排列等,进行错误推测。
前面介绍的等价类划分方法和边界值分析方法,都是着重考虑输入条件,但未考虑输入条件之间的联系。如果在测试时必须考虑输入条件的各种组合,可能的组合数将是天文数字。因此必须考虑使用一种适合于描述对于多种条件的组合,相应产生多个动作的形式来考虑设计测试用例,这就需要利用因果图。
因果图方法最终生成的就是判定表。它适合于检查程序输入条件的各种组合情况。
1.利用因果图生成测试用例的基本步骤
(1) 分析软件规格说明描述中,哪些是原因(即输入条件或输入条件的等价类),哪些是结果(即输出条件),并给每个原因和结果赋予一个标识符。
(2) 分析软件规格说明描述中的语义,找出原因与结果之间,原因与原因之间对应的是什么关系?根据这些关系,画出因果图。
(3) 由于语法或环境限制,有些原因与原因之间,原因与结果之间的组合情况不可能出现。为表明这些特殊情况,在因果图上用一些记号标明约束或限制条件。
(4) 把因果图转换成判定表。
(5) 把判定表的每一列拿出来作为依据,设计测试用例。
2.因果图的因果关系
通常,在因果图中,用Ci表示原因,Ei表示结果,其基本符号如图 10-4-10 所示。各结点表示状态,可取值“0”或“1”。“0”表示某状态不出现,“1”表示某状态出现。
·恒等:若原因出现,则结果出现。若原因不出现,则结果也不出现。
·非:若原因出现,则结果不出现。若原因不出现,反而结果出现。
·或(∨):若几个原因中有一个出现,则结果出现,几个原因都不出现,结果不出现。
·与(∧):若几个原因都出现,结果才出现。若其中有一个原因不出现,结果不出现。
图 10-4-10 因果图的图形符号
3.因果图的约束关系
为了表示原因与原因之间,结果与结果之间可能存在的约束条件,在因果图中可以附加一些表示约束条件的符号。从输入(原因)考虑,有4种约束;从输出(结果)考虑,还有一种约束,参看图 10-4-11 :
(1) E(互斥):表示a,b两个原因不会同时成立,两个中最多有一个可能成立。
(2) I(包含):表示a,b,c三个原因中至少有一个必须成立。
(3) O(唯一):表示a和b当中必须有一个,且仅有一个成立。
(4) R(要求):表示当a出现时,b必须也出现。不可能a出现,b不出现。
(5) M(屏蔽):表示当a是1时,b必须是0。而当a为0时,b的值不定。
图 10-4-11 因果图的约束符号
[例]有一个处理单价为5角钱的饮料的自动售货机软件测试用例的设计。其规格说明如下:“若投入5角钱或1元钱的硬币,押下〖橙汁〗或〖啤酒〗的按钮,则相应的饮料就送出来。若售货机没有零钱找,则一个显示〖零钱找完〗的红灯亮,这时在投入1元硬币并押下按钮后,饮料不送出来而且1元硬币也退出来;若有零钱找,则显示〖零钱找完〗的红灯灭,在送出饮料的同时退还5角硬币。”
·分析这一段说明,列出原因和结果
原因: | 1.售货机有零钱找 |
| 2.投入1元硬币 |
| 3.投入5角硬币 |
| 4.押下橙汁按钮 |
| 5.押下啤酒按钮 |
结果: | 21.售货机〖零钱找完〗灯亮 |
| 22.退还1元硬币 |
| 23.退还5角硬币 |
| 24.送出橙汁饮料 |
| 25.送出啤酒饮料 |
·画出因果图,如图 10-4-12 所示。所有原因结点列在左边,所有结果结点列在右边。
图 10-4-12 因果图
建立两个中间结点,表示处理的中间状态。
中间结点: | 11.投入1元硬币且押下饮料按钮 |
| 12.押下〖橙汁〗或〖啤酒〗的按钮 |
| 13.应当找5角零钱并且售货机有零钱找 |
| 14.钱已付清 |
·由于2与3,4与5不能同时发生,分别加上约束条件E。
·转换成判定表:
图 10-4-13 由因果图得到的判定表
在判定表中,阴影部分表示因违反约束条件的不可能出现的情况,删去。第16列与第32列因什么动作也没做,也删去。最后可根据剩下的16列作为确定测试用例的依据。
因果图方法是一个非常有效的黑盒测试方法,它能够生成没有重复性的且发现错误能力强的测试用例,而且对输入、输出同时进行了分析。
Myers提出了使用各种测试方法的综合策略:
(1) 在任何情况下都必须使用边界值分析方法。经验表明用这种方法设计出测试用例发现程序错误的能力最强。
(2) 必要时用等价类划分方法补充一些测试用例。
(3) 用错误推测法再追加一些测试用例。
(4) 对照程序逻辑,检查已设计出的测试用例的逻辑覆盖程度。如果没有达到要求的覆盖标准,应当再补充足够的测试用例。
(5) 如果程序的功能说明中含有输入条件的组合情况,则一开始就可选用因果图法。
测试用例实例--三角形用例设计
n我们可以设三角形的3条边分别为A,B,C。如果它们能够构成三角形的3条边,必须满足:
nA>0,B>0,C>0,且A+B>C,B+C>A,A+C>B。
n如果是等腰的,还要判断A=B,或B=C,或A=C。
n如果是等边的,则需判断是否A=B,且B=C,且A=C。
输入条件 | 有效等价类 | 无效等价类 |
(A>0), (1) (B>0), (2) (C>0), (3) (A+B>C), (4) (B+C>A), (5) (A+C>B), (6) | (A≤0), (7) (B≤0), (8) (C≤0), (9) (A+B≤C), (10) (B+C≤A), (11) (A+C≤B), (12) | |
是否等腰三角形 | (A=B), (13) (B=C), (14) (C=A), (15) | |
是否等边三角形 | (17) | (A≠B), (18) (B≠C), (19) (C≠A), (20) |
序号 | 【A,B,C】 | 覆盖等价类 | 输出 |
1 | 【3,4,5】 | (1),(2),(3),(4),(5),(6) | 一般三角形 |
2 | 【0,1,2】 | (7) | 不能构成三角形 |
3 | 【1,0,2】 | (8) | |
4 | 【1,2,0】 | (9) | |
5 | 【1,2,3】 | (10) | |
6 | 【1,3,2】 | (11) | |
7 | 【3,1,2】 | (12) | |
8 | 【3,3,4】 | (1),(2),(3),(4),(5),(6),(13) | 等腰三角形 |
9 | 【3,4,4】 | (1),(2),(3),(4),(5),(6),(14) | |
10 | 【3,4,3】 | (1),(2),(3),(4),(5),(6),(15) | |
11 | 【3,4,5】 | (1),(2),(3),(4),(5),(6),(16) | 非等腰三角形 |
12 | 【3,3,3】 | (1),(2),(3),(4),(5),(6),(17) | 是等边三角形 |
13 | 【3,4,4】 | (1),(2),(3),(4),(5),(6),(14),(18) | 非等边三角形 |
14 | 【3,4,3】 | (1),(2),(3),(4),(5),(6),(15),(19) | |
15 | 【3,3,4】 | (1),(2),(3),(4),(5),(6),(13),(20) |