软件构造6-5第二部分

1、Include Boundaries in the Partition

大量的错误发生在输入域的边界而不是中央
注意边界
-正整数与负整数之间的0
-数字类型的最大值和最小值
-空寂如空的字符串、空的数组、空的列表
-集合类型中的第一个元素或最后一个元素
边界值分析方法是对等价类划分方法的补充
覆盖分区的两个极限情况:
——笛卡尔积:全覆盖
每一个分区都要有一个测试用例。
对于软件构造6-5第一部分中的例子max(),共有3x5x5=75个测试用例,但是并不是所有组合情况都可能如a < b,a = 0, b = 0
——覆盖每个取值:最少1次即可
每个维度的每个取值至少被一个测试用例覆盖,如在max()的例子中我们选取了五个测试用例:
(1, 2)
(-1, -3)
(0, 0)
(Integer.MIN_VALUE, Integer.MAX_VALUE)
(Integer.MAX_VALUE, Integer.MIN_VALUE)
这五个测试用例覆盖了所有分区。
笛卡尔积测试完备,但是用例数量多,测试代价高
覆盖每个取值测试用例少,代价低,但是测试覆盖率未必高
在实际测试中要折中

2、白盒测试

2.1黑盒测试VS白盒测试

==黑盒测试完全从函数spec到处测试用例,不考虑函数内部实现。==如我们之前的例子multiply()和max()就是没有看实际代码的情况下分段并寻找边界。
白盒测试要考虑内部实现细节

2.2白盒测试

根据程序执行路径设计测试用例
白盒测试可以应用于软件测试过程的单元、集成和系统级别。通常,它在测试过程的早期执行
一个典型的白盒测试方法被称为独立/基本路径测试:对程序所有执行路径进行等价类划分,找出有代表性的简单的路径(如循环只需执行一次),设计测试用例使每一条基本路径被至少覆盖一次。

2.3举例练习

软件构造6-5第二部分
哪一个是白盒测试产生的边界值?
软件构造6-5第二部分
答案:values = [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]

3、覆盖率

3.1代码覆盖度

测试应该考虑程序内部逻辑的测试用例的代码覆盖率。
==代码覆盖度:==已有的测试用例有多大程度覆盖了被测程序
通常使用百分比来衡量。
代码覆盖度越低,测试越不充分,要做到很高的代码覆盖度就需要更多的测试用例,测试代价高。
⼀种判断测试的好坏的⽅法就是看该测试对软件的测试程度。这种测试程度也称为“覆盖率”。
一些覆盖率:
——==函数覆盖:==每个声明都已经被测试到了吗?
——==语句覆盖:==每个语句都是由某个测试用例运行的吗?
——==分支覆盖:==每一个if或while等控制操作,分支的true 和false方向都被测试了吗?
——==条件覆盖:==对于if/while/for/switch-case语句中的每个条件,分支的true和false都被测试了吗?
——路径覆盖 :分支的每一个可能的组合——通过程序的每一条路径都被测试了吗?
测试效果:**路径覆盖>分支覆盖>语句覆盖 **
测试难度:路径覆盖>分支覆盖>语句覆盖
100%的语句覆盖率在工业界是普遍的要求,但是有时由于一些不能到达的代码(如断言)不能实现
100%的分支覆盖率是很高的要求,对于安全关键的软件会要求
但是
100%的路径覆盖率
不可能的,因为这让测试用例空间以指数速度增长
在不同的软件类型与公司中,对达到哪一种标准的覆盖率有不同的要求

3.2EclEmma

Eclipse的一种代码覆盖率工具。
被执行过的代码用绿色标出
没有被执行过的代码用红色标出
分支语句中如果有一个分支一直没有被执行,则这个分支判断语句用黄色标出
软件构造6-5第二部分

3.3EclEmma举例

软件构造6-5第二部分
如图,利用EclEmma运行main函数,
当n = 3 时,n = n /2是什么颜色?
绿色
当n = 16时,n = 3 * n + 1是什么颜色?
红色
当n的初始值为多少时,while(n != 1)会是黄色?
1

4、自动化测试和回归测试

回归测试:一旦程序被修改,重新执行之前的所有测试
自动化测试:自动地运行测试对象,输入对应的测试用例并记录结果的测试
能够进行自动化测试的代码乘坐测试驱动(test driver)。
对大型或复杂程序的任何更改都是危险的。无论你是在修复另一个bug,添加新功能,还是优化代码使其更快,自动化测试都能够保证软件的行为和结果是正确的。在修改代码时频繁地运行测试可以防止程序退化——在修复新bug或添加新特性时引入其他bug。
在每次更改之后运行所有测试称为回归测试
自动化测试和回归测试通常结合起来使用,因为回顾测试只有自动化才可行。
以下哪⼀个选项是对回归测试的最好定义 ?
A.当你改变代码后应该再次进⾏测试
B.代码的每⼀个模块都应该有能够完全测试它的测试
C.测试应该在写代码之前完成,以此来检查你写的规格说明
D.当新的测试报错时,你应该重新运⾏之前的所有版本的代码直到找到开始引⼊这个bug的版本。
A

什么情况下应该重新运行所有的 JUnit 测试?
A. 在使⽤ git add/commit/push之前
B.在优化⼀个函数的性能后
C.在使⽤覆盖率⼯具时
D.在修改⼀个bug后
ABD
以下哪⼀些方法/思想对于“测试优先编程”中未写代码之前选择测试用例是有帮助的?
A. ⿊盒
B.回归
C.静态类型
D.分区
E.分区边界
F.⽩盒
G.覆盖率
ADE

5、写下你的测试策略

测试策略(根据什么来选择测试用例)非常重要,需要在程序中显式记录下来
目的:在代码评审过程中,其他人可以理解你的测试,并评判你的测试是否足够充分
(具体在第一部分5.6)

6、单元测试VS综合测试和桩(Stubs)

综合测试是对组合起来的模块进行的测试,如果综合测试报错需要大范围找错误。综合测试是必要的,因为各个模块之间的交互可能会产生bug。