|
|
知识路径: > 测试技术的分类 > 白盒测试技术 >
|
|
被考次数:2次
|
|
被考频率:
低频率
|
|
总体答错率:
27%
|
|
知识难度系数:
|
|
考试要求:
掌握
|
|
相关知识点:37个
|
|
|
|
|
通过词法分析与语法分析可以获取软件组成的重要基本因数,例如:变量标识符、过程标识符、常量等,组合这些基本因数可以得到软件的基本信息。如:
|
|
|
. 标号交叉引用表。列出在各模块中出现的全部标号,在表中标出标号的属性,包括已说明、未说明、已使用、未使用。表中还包括在模块以外的全局标号、计算标号等。
|
|
|
. 变量交叉引用表,即变量定义与引用表。在表中应标明各变量的属性,包括已说明、未说明、隐式说明以及类型及使用情况,进一步还可区分是否出现在赋值语句的右边,是否属于COMMON变量、全局变量或特权变量等。
|
|
|
. 子程序、宏和函数表。在表中列出各个子程序、宏和函数的属性,包括已定义、未定义、定义类型;以及参数表、输入参数的个数、顺序、类型,输出参数的个数、顺序、类型;已引用、未引用、引用次数等。
|
|
|
. 等价表。表中列出在等价语句或等值语句中出现的全部变量和标号。
|
|
|
. 常数表。表中列出全部数字常数和字符常数,并指出它们在哪些语句中首先被定义。
|
|
|
|
. 直接从表中查出说明/使用错误。如循环层次表、变量交叉引用表、标号交叉引用表。
|
|
|
. 为用户提供辅助信息。如子程序(宏、函数)引用表、等价表、常数表。
|
|
|
. 用来做错误预测和程序复杂度计算。如操作符和操作数的统计表等。
|
|
|
|
静态错误分析用于确定在源程序中是否有某类错误或“危险”结构。它有以下几种。
|
|
|
|
为了强化对源程序中数据类型的检查,在程序设计语言中扩充一些新的数据类型,例如,仅能在数组中使用的“下标”类型及在循环语句中当作控制变量使用的“计数器”类型。这样就可以静态预处理程序,分析程序中的类型错误。
|
|
|
|
在静态错误分析中,最广泛使用的技术就是发现引用异常。如果沿着程序的控制路径,变量在赋值以前被引用,或变量在赋值以后未被引用,这时就发生了引用异常。
|
|
|
为了检测引用异常,需要检查通过程序的每一条路径。通常采用类似深度优先的方法遍历程序流图的每一条路径,也可以建立引用异常的探测工具,这种工具包括两个表:定义表和未引用表。每张表中都包含一组变量表。未引用表中包括已被赋值但还未被引用的一些变量。
|
|
|
当扫描抵达一个出度大于1的节点V时,深度优先探测算法要求先检查最左分支的那一部分程序流图,然后再检查其他分支。在最左分支检查完之前,应把定义表与未引用表的当前内容用一个栈暂时存储起来,当最左分支检查完之后,算法控制返回到节点V,从栈中恢复该节点的定义表和未引用表的老的副表,然后再去遍历该节点的下一个分支,这个过程要继续到全部分支检查完为止。
|
|
|
|
对表达式进行分析,以发现和纠正在表达式中出现的错误。包括:
|
|
|
|
|
|
|
最复杂的一类表达式分析是对浮点数计算的误差进行检查。由于使用二进制数不精确地表示十进制浮点数,常常使计算结果出乎意料。
|
|
|
|
接口一致性是程序的静态错误分析和设计分析共同研究的题目。接口一致性的设计可以分析检查模块之间接口的一致性和模块与外部数据库之间接口的一致性。
|
|
|
程序关于接口的静态错误分析检查过程与实参在类型、函数过程之间接口的一致性,因此要检查形参与实参在类型、数量、维数、顺序、使用上的一致性;检查全局变量和公共数据区在使用上的一致性。
|
|
|
|
在软件动态测试中,程序插桩(Program Instrumentation)是一种基本的测试手段,有着广泛的应用。
|
|
|
|
程序插桩方法,简单地说,是借助往被测程序中插入操作,来实现测试目的的方法。
|
|
|
我们在调试程序时,常常要在程序中插入一些打印语句。其目的在于,希望执行程序时,打印出我们最为关心的信息。进一步通过这些信息了解执行过程中程序的一些动态特性。比如,程序的实际执行路径,或是特定变量在特定时刻的取值。从这一思想发展出的程序插桩技术能够按用户的要求,获取程序的各种信息,成为测试工作的有效手段。
|
|
|
如果我们想要了解一个程序在某次运行中所有可执行语句被覆盖(或称被经历)的情况,或是每个语句的实际执行次数,最好的办法是利用插桩技术。这里仅以计算整数X和整数Y的最大公约数程序为例,说明插桩方法的要点。下图所示给出了这一程序的流程图。图中虚线框并不是源程序的内容,而是为了记录语句执行次数而插入的。
|
|
|
|
|
|
|
程序从入口开始执行,到出口结束。凡经历的计数语句都能记录下该程序点的执行次数。如果我们在程序的入口处还插入了对计数器C(i)初始化的语句,在出口处插入了打印这些计数器的语句,就构成了完整的插桩程序,它便能记录并输出在各程序点上语句的实际执行次数。如下图所示表示了插桩后的程序,图中箭头所指均为插入的语句(源程序语句略)。
|
|
|
|
|
通过插入的语句获取程序执行中的动态信息,这一做法如同在刚研制成的机器特定部位安装记录仪表一样。安装好以后开动机器试运行,我们除了可以从机器加工的成品检验得知机器的运行特性外,还可通过记录仪表了解其动态特性。这就相当于在运行程序以后,一方面可检验测试的结果数据,另一方面还可借助插入语句给出的信息了解程序的执行特性。正是这个原因,有时把插入的语句称为“探测器”,借以实现“探查”或“监控”的功能。
|
|
|
在程序的特定部位插入记录动态特性的语句,最终是为了把程序执行过程中发生的一些重要历史事件记录下来。例如,记录在程序执行过程中某些变量值的变化情况,变化的范围等。又如本书前面章节中所讨论的程序逻辑覆盖情况,也只有通过程序的插桩才能取得覆盖信息。实践表明,程序插桩方法是应用很广的技术,特别是在完成程序的测试和调试时非常有效。
|
|
|
|
|
|
|
|
|
其中前两个问题需要结合具体情况解决,并不能给出笼统的回答。至于第三个问题,需要考虑如何设置最少探测点的方案。例如,在如上图所示的程序入口处,若要记录语句Q=X和R=Y的执行次数,只需插入C(1)=C(1)+1这样一个计数语句就够了,没有必要在每个语句之后都插入一个计数语句。在一般的情况下,我们可以认为,在没有分支的程序段中只需一个计数语句。但程序中如果出现了多种控制结构,使得整个结构十分复杂,则为了在程序中设计最少的计数语句,需要针对程序的控制结构进行具体的分析。这里我们以Fortran程序为例,列举至少应在哪些部位设置计数语句:
|
|
|
|
|
|
. do、do while、do until及do终端语句之后;
|
|
|
. block-if、else if、else及endif语句之后;
|
|
|
|
|
|
|
|
在程序中的特定部位插入某些用以判断变量特性的语句,使得程序执行中这些语句得以证实,从而使程序的运行特性得到证实。我们把插入的这些语句称为断言(assertions)。这一作法是程序正确性证明的基本步骤,尽管算不上严格的证明,但方法本身仍然是很实用的。下面以求两个非负数NUM和DEN之商的Wensley迭代算法为例,对断言语句的作用作一简要说明。
|
|
|
假定两个非负数中,NUM小于M(即所得之商小于1),算法中只用到加、减及除2的运算。该迭代算法的程序如下图所示。
|
|
|
|
|
从程序中可以看出,在每次迭代中由分母得到的变量B以及权增量W都要缩小一半,而且变量A随着迭代次数的增加将接近分子。这些粗略的观察和分析可以用以下4个断言语句表达,在每次迭代开始时4个断言必定为真:
|
|
|
|
|
|
|
|
|
|
假定我们所用的编译系统能够处理表达式形式的断言语句,插入断言以后的程序如下图所示。其中带有标记@的语句是断言语句。新增加的变量K只是在计算第①断言时用到。
|
|
|
|
|
|
|
|
③将W的值代入DEN * W/2,则得B的初值:B=DEN/2。
|
|
|
|
以上说明了这些断言在初始状态下为真。如果继续迭代,要证明断言为真,就必须证明无论if-then结构中执行什么路径这些断言都为真。我们先来考虑在初始测试中NUM-A-B≥0为假,即检验失败,然后给出程序向量的新值(A′,B′,W′,Q′和K′),我们有:
|
|
|
|
|
|
|
|
|
|
|
③ B*=B/2=DEN * W/4=DEN* W*/2
|
|
|
④把A和B代入(NUM-A-B<0),得到NUM-DEN * Q-DEN * W/2<0,对此关系式两端除以DEN,并加Q,得到,由于Q′=Q, W′=W/2,我们有NUM/DEN-W**,且Q≤NUM/DEN。
|
|
|
如果if-then检验成立,再来看4个断言。使用A″,B″,W″,Q″和K″作为新的程序向量,我们有:
|
|
|
|
②A"=DEN * Q+DEN * W/2=DEN *(Q+W/2)=DEN * Q"
|
|
|
③ B″=B/2=DEN * W/4=DEN * W″/2
|
|
|
④代入(NUM-A-B ≥ 0),并作同前的变换,得到NUM/DEN - W″/2
|
|
|
总之,无论执行哪一路径,在每一迭代的开始,4个断言均为真。尽管并未考虑输出断言,但是我们知道,第④断言成立,由于W
|
|
|