一、实验目的
1.掌握等逻辑覆盖测试法;
2.掌握基本路径测试法;
3.掌握基于Junit的单元测试。
二、实验内容
1.为以下判断等级的程序段设计一组测试用例,要求分别满足语句覆盖、判定覆盖、条件覆盖、判断-条件覆盖、条件组合覆盖。
1. public char function(int x, int y) { 2. 1. char t; 3. 2. if((x>= 90) &&(y>= 90)){ 4. 3. t ='A'; 5. }else { 6. 4. if((x+ y)>= 165){ 7. 5. t = 'B'; 8. } else{ 9. 6. t = 'C'; 10. 7. } 11. 8. } 12. 9. return t; 13. }
2.下面的程序代码(Java语言)的功能是将一个正整数分解质因数。例如,输入90,打印出90=2*3*3*5。要求使用基本路径法设计测试用例。
1. public static void zhiyinshu( int n){ 2. 1. int k=2; 3. 1. System.out.print(n + "="); //输出:n= 4. 2. while(k<= n){ 5. 3. if(k == n){ 6. 4. System.out.println(n); // 输出: n 7. 4. break; 8. }else { 9. 5. if(n%k==0){ 10. 6. System.out.print(k +"*");//输出:k* 11. 6. n=n/k; 12. }else { 13. 7. k++; 14. 8. } 15. 9. } 16. }
3. 使用Junit对下面程序进行单元测试。(每个方法各设计任意1组)
1. public class Calculator { 2. 3. public double add(double a,double b){ 4. return a+b; 5. } 6. 7. public double sub(double a,double b){ 8. return a-b; 9. } 10. 11. public double multiply(double a, double b){ 12. return a*b; 13. } 14. 15. public double div(double a, double b){ 16. return a/b; 17. } 18. }
三、实验步骤
1. 用逻辑覆盖法
1)画出该程序的控制流图(用代码行前的编号或行号表示节点),并用Ti、Fi标记各条件。
程序的控制流图是描述程序控制流的一种图示方法。控制流图是退化的程序流程图,图中每个处理都退化成一个节点,流线变成连接不同节点的有向弧。
其中,圆圈称为控制流图的一个节点,表示一个或多个无分支的语句或源程序语句;箭头称为边或连接,代表控制流。
在将程序流程图简化成控制流图时,应注意:
①在选择或多分支结构中,分支的汇聚处应有一个汇聚节点;
②边和节点圈定的区域叫做区域,当对区域计数时,图形外的区域也应记为一个区域。
2.基本路径法
1)基本路径测试是在程序控制流图的基础上,通过分析控制构造的环路复杂性,导出基本可执行路径集合,从而设计测试用例的方法。
2)基本路径测试主要包含以下四个方面:
(1) 绘制出程序的程序控制流图。根据程序流程图,绘制出程序的控制流图。(用代码行前的编号或行号表示节点)
(2) 计算程序环路复杂度。环路复杂度是一种为程序逻辑复杂性提供定量测度的软件度量,将该度量用于计算程序的基本独立路径数目,这是程序中每个可执行语句至少执行一次所必须的最少测试用例数。
计算环路复杂性的方法有三种:
①定义环路复杂性为V(G),E为控制流图的边数,V为控制流图的节点数,则有公式V(G)=E-N+2;
②定义P为控制流图中的判定节点数,则有公式V(G)=P+1;
③控制流图中的区域数为R,则V(G)=R。
(3) 找出独立路径。通过程序的控制流图导出基本路径集,列出程序的独立路径。
(4) 设计测试用例。根据程序结构和程序环路复杂性设计用例输入数据和预期结果,确保基本路径集中的每一条路径的执行。
3. 使用Junit对下面程序进行单元测试。(P106)
1)类 Person使用 JUnit 进行测试:
(1)先新建一个类 Person:
(2)创建测试类:
(3) 点击右键,选择[Run As],点击[JUnit Test]
那么,在整个测试步骤中,我们需要注意到什么呢?
➢测试方法上必须使用@Test
➢测试方法必须使用 public void 进行修饰
➢新建一个目录来存放测试代码
➢测试类的包应该和被测试类的包一样,如图:
➢测试单元中的每个方法一定要能够独立测试,其方法不能有任何依赖
2、使用 Eclipse 创建 JUnit 测试类
案例2:使用工具创建 JUnit 测试类,并进行测试。
步骤如下:
1) 选择要测试的方法,右击 New,选择 other
2) 在[java]下[JUnit]选择[JUnit Test Case],如图:
3) 测试类目录选择 test,如图:
4) 点击[Next],如图:
5) 勾选你要测试的方法,点击[Finish]如图:
6) 在这个步骤中,如果之前没有添加 JUnit 的 jar 包,则会弹出提示:
点选[OK]即可,如果已经添加过 jar 包,则不会弹出此提示。 最后,生成的代码如下
然后,在这个基础上修改你的测试代码即可。
在测试中结果中关于 Failure 和 error 的解释:
➢ Failure 一般由测试单元使用断言方法判断失败引起的,这个报错,说明测试点发现了问题,即程序输出 的结果和我们预期的不一样
➢ error 是由代码异常引起的,它可以产生代码本身的错误,也可以是测试代码中的一个隐藏 bug
如果我们勾选上这四个方法后生成的代码又是什么样呢?
勾选后生成代码如图:
同样,右键,选择[Run As],点击[JUnit Test],运行结果:
由此,我们总结如下:
⚫ @BeforeClass
修饰的方法会在所有方法被调用前执行,且该方法时静态的,所以当测试类被加载后就接着运行它,而且在内 存中他只会存在一份实例,他比较适合加载配置文件(针对所有测试,只执行一次 )。
⚫ @AfterClass
所修饰的方法通常用来对资源管理,如关闭数据库连接(针对所有测试,只执行一次 )。
⚫ @Before 和@After
会在每个测试方法前后各执行一次。
⚫ @Test:测试方法,在这里可以测试期望异常和超时时间
四、实验结果
1.逻辑覆盖法
控制流程图:
测试用例:
(1)语句覆盖的测试用例:
编号 |
测试用例 |
语句 |
执行路径 |
1 |
x=100,y=100 |
1,3 |
1,2,3,8,9 |
2 |
x=85,y=85 |
1,5 |
1,2,4,5,7,8,9 |
3 |
x=60,y=60 |
1,7 |
1,2,4,6,7,8,9 |
(2)判定覆盖的测试用例:
编号 |
测试用例 |
判定 |
执行路径 |
1 |
x=100,y=100 |
2,4 |
1,2,3,8,9 |
2 |
x=85,y=85 |
2,4 |
1,2,4,6,7,8,9 |
3 |
x=60,y=60 |
2,4 |
1,2,4,6,7,8,9 |
(3)条件覆盖的测试用例:
编号 |
测试用例 |
条件 |
执行路径 |
1 |
x=100,y=100 |
2,4 |
1,2,3,8,9 |
2 |
x=85,y=85 |
2,4 |
1,2,4,5,7,8,9 |
3 |
x=60,y=60 |
2,4 |
1,2,4,6,7,8,9 |
(4)判定-条件覆盖的测试用例
编号 |
测试用例 |
条件 |
执行路径 |
1 |
x=100,y=100 |
2,4 |
1,2,3,8,9 |
2 |
x=85,y=85 |
2,4 |
1,2,4,5,7,8,9 |
3 |
x=60,y=60 |
2,4 |
1,2,4,6,7,8,9 |
(5)条件组合覆盖的测试用例
编号 |
测试用例 |
条件 |
执行路径 |
1 |
x=100,y=100 |
2,4 |
1,2,3,8,9 |
2 |
x=90,y=85 |
2,4 |
1,2,4,6,7,8,9 |
3 |
x=85,y=90 |
2,4 |
1,2,4,5,7,8,9 |
4 |
x=60,y=60 |
2,4 |
1,2,4,6,7,8,9 |
2.基本路径法
程序控制流图:
程序环路复杂度: V(G)=P+1=3+1=4
独立路径:
1-2-9 |
1-2-3-4-9 |
1-2-3-5-7-8-2-3-4-9 |
1-2-3-5-6-8-2-3-4-9 |
测试用例:
编号 |
输入数据 |
预期输出 |
执行路径 |
1 |
n=2 |
2=2 |
1-2-3-4-9 |
2 |
n=3 |
3=3 |
1-2-3-5-7-8-2-3-4-9 |
3 |
n=4 |
4=2*2 |
1-2-3-5-6-8-2-3-4-9 |
3.单元测试
程序代码:
1. public class Calculator { 2. 3. public double add(double a,double b){ 4. return a+b; 5. } 6. 7. public double sub(double a,double b){ 8. return a-b; 9. } 10. 11. public double multiply(double a, double b){ 12. return a*b; 13. } 14. 15. public double div(double a, double b){ 16. return a/b; 17. } 18. }
五、实验总结
在实验过程中遇到了各种各样的问题,测试所用方法理解不清晰。通过与同学们相互讨论,所有问题都迎刃而解,并且成功完成了实验。