5.4.3 实例分析
1.实例1
在这一部分以图5-16中的粗体部分path1作为输入来为输入参数x生成用例。由path1上的约束可知,若想成功覆盖stmt_4,即输出“path1”,必须满足路径上的3个约束。变量x的初始区间为(-∞,+∞),通过x>90和x<150这两个约束对x进行区间运算,求得x的区间为[91,149],即D=[91,149]。到第三个if节点时,遇到包含库函数的约束isupper(x)≠0,根据关键字isupper进行语义解析,可以判定此库函数的语义是判定ASSIC为x的字符是不是大写字母且只有一个输入参数。根据算法5-5可确定isupper的求反操作L isupper。求反操作L isupper根据ASIIC规则将x的取值区间限定在[65,90],即经过分支限定算法,求得D′=[65,90],此操作相当于将约束3变为图5-18所示的“x>=65&&x<=90”。满足库函数约束的x的取值区间D′和满足前两个约束的x的取值区间D进行相交运算可得到满足路径上所有约束的条件,完成覆盖Path1的要求。D′∩D=[65,90]∩[91,145]=∅,由此可知,不存在这样一个x,同时满足路径上的所有约束,即此路径不可达。有了路径不可达这个判定结果,用例求解算法就不会再在[91,149]这个区间上做无用功,而是直接返回,节约了时间和资源。

图5-18 程序test及其经过库函数反操作后的形式
2.实例2
这一部分以pow(x,y)=9为待求库函数约束为pow()的两个输入参数x、y生成测试用例。
库函数pow(x,y)的参数标准类型均为double,但是此处为了说明简单,我们将x和y的类型设为整型。如图5-19所示,假设变量x和y的初始区间均为[-10,+10],通过x>2,x<4两个约束对变量x进行区间运算,求得x的区间为[3,3],y的区间仍为[-10,+10]。当用例生成程序分析到“if(pow(x,y)==9)”这个节点时,遇到了包含库函数的约束pow(x,y)=9,根据关键字pow对此库函数进行语义解析,进而判定函数名为pow的库函数是个幂次函数,在此约束中表示x y=9,且参数列表中有两个输入参数。由于x、y中变量x的区间是只有一个值的单值区间,因此根据算法5-5,对x在其区间中选取唯一整数x=3后返回针对y的求反操作L pow,由数学定义可知y=log x 9,由此求得y的取值为2,满足了约束3的条件,可成功覆盖语句“printf("path1")”。通过对库函数pow的语义解析以及求反操作处理,明确了变量x、y的关系,这就使得在给x成功赋值后,y就不会在[-10,+10]中盲目选值,提高了用例生成成功率。
(https://www.daowen.com)
图5-19 被测程序test1
在图5-20中,同样假设变量x和y的初始区间为[-10,+10],但是此时变量y的区间是确定的只有一个值的单值区间。由于库函数中参数列表的赋值顺序发生改变,因此库函数对应的反操作L pow也发生了改变,不再是y=log x 9,而是x=y 9,当y=2时可以求得x的取值为3或-3,满足了语句覆盖路径上的所有条件,避免了为x在其区间[-10,10]上的盲目选值,同样提高了用例生成成功率。图5-21和图5-22分别描述了上述两个计算过程。

图5-20 被测程序test2

图5-21 被测程序test1的区间求解过程

图5-22 被测程序test2的区间求解过程