B.1  常用的黑盒测试方法

B.1.1  功能分解
功能分解是将规格说明中每一个功能加以分解，确保各个功能被全面地测试。功能分解是一种较常用的方法。
功能分解方法的步骤为：
a. 使用程序设计中的功能抽象方法把程序分解为功能单元；
b. 使用数据抽象方法产生测试每个功能单元的数据。
功能抽象中程序被看成一种抽象的功能层次，每个层次可标识被测试的功能，层次结构中的某一功能由其下一层功能定义。按照功能层次进行分解，可以得到众多的最低层次的子功能，以这些子功能为对象，进行测试用例设计。
数据抽象中，数据结构可以由抽象数据类型的层次图来描述，每个抽象数据类型有其取值集合。
程序的每一个输入和输出量的取值集合用数据抽象来描述。

B.1.2  等价类划分
等价类划分是在分析规格说明的基础上，把程序的输入域划分成若干部分，然后在每部分中选取代表性数据形成测试用例。
等价类划分方法的步骤为：
a. 划分有效等价类：对规格说明是有意义、合理的输入数据所构成的集合；
b. 划分无效等价类：对规格说明是无意义、不合理的输入数据所构成的集合；
c. 为每一个等价类定义一个唯一的编号；
d. 为每一个等价类设计一组测试用例，确保覆盖相应的等价类。

B.1.3  边界值分析
边界值分析是使用等于、小于或大于边界值的数据对程序进行测试的方法。边界值分析方法的步骤为：
a. 通过分析规格说明，找出所有可能的边界条件；
b. 对每一个边界条件，给出满足和不满足边界值的输入数据；
c. 设计相应的测试用例。
对满足边界值的输入可以发现计算错误，对不满足的输入可以发现域错误。该方法会为其他测试方法补充一些测试用例，绝大多数测试都会用到本方法。

B.1.4  判定表
判定表由四部分组成：条件桩，条件条目，动作桩，动作条目。任何一个条件组合的取值及其相应要执行的操作构成规则，条目中的每一列是一条规则。
条件引用输入的等价类，动作引用被测软件的主要功能处理部分，规则就是测试用例。
建立并优化判定表，把判定表中每一列表示的情况写成测试用例。该方法的使用有以下要求：
a. 规格说明以判定表形式给出，或是很容易转换成判定表；
b. 条件的排列顺序不会影响执行哪些操作；
c. 规则的排列顺序不会影响执行哪些操作；
d. 每当某一规则的条件已经满足，并确定要执行的操作后，不必检验别的规则；
e. 如果某一规则的条件得到满足，将执行多个操作，这些操作的执行与顺序无关。

B.1.5  因果图
因果图方法是通过画因果图，把用自然语言描述的功能说明转换为判定表，然后为判定表的每一列设计一个测试用例。
因果图方法的步骤为：
a. 分析规格说明，引出原因（输入条件）和结果（输出结果），并给每个原因和结果赋予一个标识符；
b. 分析规格说明中语义的内容，并将其表示成连接各个原因和各个结果的“因果图”；
c. 在因果图上标明约束条件；
d. 通过跟踪因果图中的状态条件，把因果图转换成有限项的判定表；
e. 把判定表中每一列表示的情况生成测试用例。
如果规格说明中含有输入条件的组合，宜采用本方法。有些软件的因果图可能非常庞大，以致于根据因果图得到的测试用例数目非常大，此时不宜使用本方法。

B.1.6  场景法
通常，对由事件触发控制流程的软件，事件触发时的情景形成了场景。同一事件可能有不同的触发顺序和处理结果。因此，用况场景不仅描述了软件预期的或所希望的使用方式，也描述了流经用况的路径，包括从用况开始到结束遍历这条路径上所有的基本流和备选流。基本流是经过用况的最简单的路径。一个备选流可能从基本流开始，也可能起源于另一个备选流，备选流在某个特定条件下执行，最后可能重新加入基本流中，或者终止用况而不再重新加入到某个流中。按照经过用况的每个可能路径，可以确定不同的用况场景。每个用况场景的执行都是在特定条件触发下发生的，因此，可根据某个特定条件为每个场景生成测试用例。
场景法的步骤为：
a. 确定用况的基本流和备选流；
b. 根据基本流和备选流确定不同的场景；
c. 针对每一个场景设计测试用例，可采用矩阵或判定表设计测试用例；
d. 对 c.中设计的全部测试用例进行审验，取消多余或等效的测试用例，确保测试用例准确和适度；
e. 针对每一个测试用例设计测试数据。

B.1.7  功能图法
功能图法用功能图形式化地表示程序的功能说明，并生成测试用例。测试用例是由测试中经过的一系列状态和在每个状态中必须依靠输入/输出数据满足的一对条件组成。
功能图模型由状态转移图和逻辑功能模型构成。状态转移图用于表示输入数据序列以及相应的输出数据，在状态转移图中，由输入数据和当前状态决定输出数据和后续状态。逻辑功能模型用于表示在状态中输入条件和输出条件之间的对应关系，且输出数据仅由输入数据决定。逻辑功能模型可用因果图和判定表来描述。
功能图法生成测试用例的步骤为：
a. 由逻辑功能模型导出测试用例。对每个状态用因果图法生成局部测试用例；
b. 由状态转移图导出测试用例。用节点代替状态，用弧代替迁移，将状态转移图转化为控制流图形式。用白盒测试方法中介绍的控制流测试生成路径测试用例；
c. 合成测试用例。把局部测试用例分配给测试路径上的某一个状态，将路径测试用例与局部测试用例结合在一起，生成实用的功能图的测试用例。

B.1.8  随机测试
随机测试指测试输入数据是在所有可能输入值中随机选取的。测试人员只需规定输入变量的取值区间，在需要时提供必要的变换机制，使产生的随机数服从预期的概率分布。该方法获得预期输出比较困难，多用于可靠性测试和系统强度测试。

B.1.9  猜错法
猜错法是有经验的测试人员，通过列出可能有的错误和易错情况表，写出测试用例的方法。

B.1.10  正交试验法
正交试验法是从大量的实验点中挑出适量的、有代表性的点，应用正交表，合理地安排实验的一种科学的实验设计方法。
利用正交试验法来设计测试用例时，首先要根据被测软件的规格说明书找出影响功能实现的操作对象和外部因素，把它们当作因子，而把各个因子的取值当作状态，生成二元的因素分析表。然后，利用正交表进行各因子的状态的组合，构造有效的测试输入数据集，并由此建立因果图。这样得出的测试用例的数目将大大减少。

B.1.11  组合测试法
组合测试是一种测试用例的生成方法。被测对象的不同输入参数分别有若干个取值。可以为不同输入参数轮流取不同值，以组合生成一组测试用例集。在黑盒测试中，组合的参数可以是软件的输入数据；在白盒测试中，组合的参数通常对应于单元的输入参数。
对组合生成的测试用例集的检验，是看其能否满足不同的组合强度覆盖要求。常见的组合强度覆盖有单一选择、基本选择、成对组合、全组合和 K 强度组合等。

B.1.12  蜕变测试法
蜕变测试是一种测试结果验证方法。当被测软件结构复杂，单个测试用例的测试结果的正确性难以判定时，可以通过构造蜕变关系，验证该测试用例与其他相关测试用例的测试结果是否满足蜕变关系，如果不满足蜕变关系，则这些测试用例不通过，并由此发现失效。蜕变测试可以与其他测试方法共同使用，通过蜕变测试对测试结果进行验证，或生成补充测试用例。

B.2  常用的白盒测试方法

B.2.1  控制流测试
依据控制流程图产生测试用例，通过对不同控制结构成份的测试验证程序的控制结构。所谓验证某种控制结构即指使这种控制结构在程序运行中得到执行，也称这一过程为覆盖。常用的覆盖有语句覆盖、分支覆盖、条件覆盖、条件组合覆盖、修正的条件判定覆盖（MC/DC）、路径覆盖等。
控制流测试的步骤为：
a. 将程序流程图转换成控制流图；
b. 经过语法分析求得路径表达式；
c. 生成路径树；
d. 进行路径编码；
e. 经过译码得到执行的路径；
f. 通过路径枚举产生特定路径的测试用例。

B.2.2  数据流测试
数据流测试是用控制流程图对变量的定义和引用进行分析，查找出未定义的变量或定义了而未使用的变量，这些变量可能是拼错的变量、变量混淆或丢失了语句。数据流测试一般使用工具进行。
数据流测试通过一定的覆盖准则，检查程序中每个数据对象的每次定义、使用和消除的情况。数据流测试方法的步骤为：
a. 将程序流程图转换成控制流图；
b. 在每个链路上标注对有关变量的数据操作的操作符号或符号序列；
c. 选定数据流测试策略；
d. 根据测试策略得到测试路径；
e. 根据路径可以获得测试输入数据和测试用例。
动态数据流异常检查在程序运行时执行，获得的是对数据对象的真实操作序列，克服了静态分析检查的局限，但动态方式检查是沿与测试输入有关的一部分路径进行的，检查的全面性和程序结构覆 盖有关。

B.2.3  程序变异
程序变异是一种错误驱动测试方法。该方法针对某类特定程序错误，定义一系列的变异算子，将变异算子作用于程序代码，产生若干符合语法的变异体，实际是将故障植入程序，用测试数据逐个测试变异体。根据变异程度的不同,可以分为强变异和弱变异。程序变异方法具有针对性强、系统性强的特点，在对软件进行测试的同时，也可评价测试用例集的错误检测能力。

B.2.4  程序插桩
程序插桩是向被测程序中插入操作以实现测试目的方法。程序插桩不应该影响被测程序的运行过程和功能。
有很多的工具有程序插桩功能。由于数据记录量大，手工进行将是一件很烦琐的事。

B.2.5  域测试
域测试是要判别程序对输入空间的划分是否正确。该方法限制太多，使用不方便，供有特殊要求
的测试使用。

B.2.6  符号求值
符号求值是允许数值变量取“符号值”以及数值。符号求值可以检查公式的执行结果是否达到程序预期的目的，也可以通过程序的符号执行，产生出程序的路径，用于产生测试数据。
符号求值最好使用工具，在公式分支较少时手工推导也是可行的。
