第二次实验报告:结构性测试
被测试代码链接:http://www.cnblogs.com/lyz007/p/6627535.html
一、实验目的
掌握基于覆盖理论与基本路径的基本白盒测试方法和实践
二、实验要求
运用逻辑覆盖测试的覆盖准则设计被测程序的测试用例,并运行测试用例检查程序的正确与否,给出程序缺陷小结。
三、实验内容
根据各位同学自己的被测程序,分别作出各类白盒测试技术的用例设计和相应的Junit脚本。
所有的覆盖的技术:语句覆盖、判定覆盖、条件覆盖、判定/条件覆盖、组合覆盖、路径覆盖,基本路径测试方法。
包括的内容有:
1) 被测代码
1 package triangle; 2 import java.util.Scanner; 3 public class Triangle { 4 public final static int DENGBIAN = 0; 5 public final static int DENGYAO = 1; 6 public final static int ZHIJIAO = 2; 7 public final static int YIBAN = 3; 8 private int a; 9 private int b; 10 private int c; 11 protected int checkType()//判断三角形种类 12 { 13 if(a==b&&a==c&&b==c) 14 return DENGBIAN; 15 if(a==b||a==c||b==c) 16 return DENGYAO; 17 if(a*a+b*b==c*c||a*a==b*b+c*c||b*b==a*a+c*c) 18 return ZHIJIAO; 19 return YIBAN; 20 } 21 protected boolean checkTheOne()//检查范围条件 22 { 23 if((a>=1&&a<=100)&&(b>=1&&b<=100)&&(c>=1&&c<=100)) 24 return true; 25 else 26 return false; 27 } 28 protected boolean checkTheTwo()//检查是否组成三角形 29 { 30 if((a<(b+c))&&(b<(a+c))&&(c<(a+b))) 31 return true; 32 else 33 return false; 34 } 35 public void triangle( int a, int b, int c)//题目要求的函数 36 { 37 this.a = a; 38 this.b = b; 39 this.c = c; 40 if(!checkTheOne()) 41 { 42 System.out.println("边的值不在范围内"); 43 } 44 else if(!checkTheTwo()) 45 { 46 System.out.println("不构成三角形"); 47 } 48 else 49 { 50 switch(checkType()) 51 { 52 case DENGBIAN: System.out.println("等边三角形");break; 53 case DENGYAO: System.out.println("等腰三角形");break; 54 case ZHIJIAO: System.out.println("直角三角形");break; 55 case YIBAN: System.out.println("一般三角形");break; 56 } 57 } 58 } 59 public static boolean checkNum(String[] str){ 60 //判断输入是否为三个字符串 61 if(str.length != 3){ 62 return false; 63 } 64 //利用正则表达式判断三个字符串是否为纯数字 65 for(int i = 0; i < 3; i++){ 66 if(str[i].matches("[0-9]+")){ 67 continue; 68 } 69 else{ 70 return false; 71 } 72 } 73 return true; 74 } 75 public static void main(String[] args) 76 { 77 Triangle t1 = new Triangle(); 78 String inputStr; 79 String[] str=null; 80 Scanner scanner = new Scanner(System.in); 81 while (true) { 82 System.out.println("请输入三角形的三条边:"); 83 inputStr = scanner.nextLine(); 84 //分割成字符串数组 85 str=inputStr.split(","); 86 //Judge方法判断输入格式 87 if(checkNum(str)){ 88 //转整形数据并传入triangle方法 89 t1.triangle(Integer.parseInt(str[0]),Integer.parseInt(str[1]),Integer.parseInt(str[2])); 90 }else{ 91 System.out.println("输入格式错误!"); 92 } 93 } 94 } 95 }
2)依据覆盖技术,测试用例列表:
基本路径图:
(I)语句覆盖:
A-B-C-D-E-F-O和A-B-C-D-E-G-H-O
A-B-C-D-E-G-I-J-O和A-B-C-D-E-G-I-K-O
A-B-C-D-L-O和A-B-C-M-O和A-B-N-O
测试用例:
用例ID |
输入值 |
执行路径 |
预期输出 |
实际结果 |
是否通过 |
||
a |
b |
c |
|||||
1 |
1 |
1 |
1 |
A-B-C-D-E-F-O |
等边三角形 |
等边三角形 |
√ |
2 |
2 |
2 |
3 |
A-B-C-D-E-G-H-O |
等腰三角形 |
等腰三角形 |
√ |
3 |
3 |
4 |
5 |
A-B-C-D-E-G-I-J-O |
直角三角形 |
直角三角形 |
√ |
4 |
3 |
5 |
6 |
A-B-C-D-E-G-I-K-O |
一般三角形 |
一般三角形 |
√ |
5 |
1 |
1 |
3 |
A-B-C-D-L-O |
不构成三角形 |
不构成三角形 |
√ |
6 |
101 |
99 |
99 |
A-B-C-M-O |
边的值不在范围内 |
边的值不在范围内 |
√ |
7 |
1 |
1 |
Null |
A-B-N-O |
输入格式错误! |
输入格式错误! |
√ |
(II)分支覆盖(判断覆盖):
A-B-C-D-E-F-O和A-B-C-D-E-G-H-O
A-B-C-D-E-G-I-J-O和A-B-C-D-E-G-I-K-O
A-B-C-D-L-O和A-B-C-M-O和A-B-N-O
测试用例:
用例ID |
输入值 |
执行路径 |
预期输出 |
实际结果 |
是否通过
|
||
a |
b |
c |
|||||
1 |
1 |
1 |
1 |
A-B-C-D-E-F-O |
等边三角形 |
等边三角形 |
√ |
2 |
2 |
2 |
3 |
A-B-C-D-E-G-H-O |
等腰三角形 |
等腰三角形 |
√ |
3 |
3 |
4 |
5 |
A-B-C-D-E-G-I-J-O |
直角三角形 |
直角三角形 |
√ |
4 |
3 |
5 |
6 |
A-B-C-D-E-G-I-K-O |
一般三角形 |
一般三角形 |
√ |
5 |
1 |
1 |
3 |
A-B-C-D-L-O |
不构成三角形 |
不构成三角形 |
√ |
6 |
101 |
99 |
99 |
A-B-C-M-O |
边的值不在范围内 |
边的值不在范围内 |
√ |
7 |
1 |
1 |
Null |
A-B-N-O |
输入格式错误! |
输入格式错误! |
√ |
(III)路径覆盖:
A-B-C-D-E-F-O和A-B-C-D-E-G-H-O
A-B-C-D-E-G-I-J-O和A-B-C-D-E-G-I-K-O
A-B-C-D-L-O和A-B-C-M-O和A-B-N-O
测试用例:
用例ID |
输入值 |
执行路径 |
预期输出
|
实际结果 |
是否通过
|
||
a |
b |
c |
|||||
1 |
1 |
1 |
1 |
A-B-C-D-E-F-O |
等边三角形 |
等边三角形 |
√ |
2 |
2 |
2 |
3 |
A-B-C-D-E-G-H-O |
等腰三角形 |
等腰三角形 |
√ |
3 |
3 |
4 |
5 |
A-B-C-D-E-G-I-J-O |
直角三角形 |
直角三角形 |
√ |
4 |
3 |
5 |
6 |
A-B-C-D-E-G-I-K-O |
一般三角形 |
一般三角形 |
√ |
5 |
1 |
1 |
3 |
A-B-C-D-L-O |
不构成三角形 |
不构成三角形 |
√ |
6 |
101 |
99 |
99 |
A-B-C-M-O |
边的值不在范围内 |
边的值不在范围内 |
√ |
7 |
1 |
1 |
Null |
A-B-N-O |
输入格式错误! |
输入格式错误! |
√ |
(IV)条件覆盖:各个条件取真或假的可能至少执行一次
编号 |
Checknum() |
a>=1 |
a<=100 |
b>=1 |
b<=100 |
c>=1 |
c<=100
|
a>=1 &&a<=100&&b>=1 &&b<=100&&c>=1&&c<=100 |
覆盖路径 |
1 |
T |
T |
T |
T |
T |
T |
T |
T |
B-C-D |
2 |
F |
NULL |
NULL |
T |
T |
T |
T |
F |
B-N |
3 |
T |
F |
T |
F |
T |
F |
T |
F |
B-C-M |
4 |
T |
T |
F |
T |
F |
T |
F |
F |
B-C-M |
下表的先决条件是边已在(a>=1&&a<=100)&&(b>=1&&b<=100)&&(c>=1&&c<=100)内,根据实际编写覆盖条件
编号 |
a<b+c |
b<a+c |
c<a+b |
a<b+c &&b<a+c&& c<a+b |
覆盖路径 |
1 |
T |
T |
F |
F |
D-L |
2 |
T |
T |
T |
T |
D-E |
3 |
T |
F |
T |
F |
D-L |
4 |
F |
T |
T |
F |
D-L |
下表的先决条件是边已在a<b+c &&b<a+c&& c<a+b内,根据实际编写覆盖条件
编号 |
a==b |
a==c |
b==c |
a==b&&a==c&&b==c |
覆盖路径 |
1 |
T |
F |
F |
F |
E-G |
2 |
T |
T |
T |
T |
E-F |
3 |
F |
F |
F |
F |
E-G |
4 |
F |
T |
F |
F |
E-G |
5 |
F |
F |
T |
F |
E-G |
下表先决条件是非等边三角形才能覆盖到的路径
编号 |
a==b |
a==c |
b==c |
a==b||a==c||b==c |
覆盖路径 |
1 |
T |
F |
F |
T |
G-H |
2 |
F |
F |
F |
F |
G-I |
3 |
F |
T |
F |
T |
G-H |
4 |
F |
F |
T |
F |
G-H |
编号 |
a*a+b*b==c*c |
b*b+c*c==a*a |
a*a+c*c==b*b |
a*a+b*b==c*c || b*b+c*c==a*a || a*a+c*c==b*b |
覆盖路径 |
1 |
T |
F |
F |
T |
I-J |
2 |
T |
T |
F |
T |
I-J |
3 |
T |
T |
T |
T |
I-J |
4 |
T |
F |
T |
T |
I-J |
5 |
F |
F |
F |
F |
I-K |
6 |
F |
T |
F |
T |
I-J |
7 |
F |
F |
T |
T |
I-J |
8 |
F |
T |
T |
T |
I-J |
测试用例:
用例ID |
输入值 |
执行路径 |
预期输出 |
实际结果 |
是否通过
|
||
a |
b |
c |
|||||
1 |
1 |
1 |
1 |
A-B-C-D-E-F-O |
等边三角形 |
等边三角形 |
√ |
2 |
NULL |
1 |
1 |
A-B-N-O |
输入格式错误! |
输入格式错误! |
√ |
3 |
-1 |
-1 |
-1 |
A-B-C-M-O |
边的值不在范围内 |
边的值不在范围内 |
√ |
4 |
0 |
0 |
0 |
A-B-C-M-O |
边的值不在范围内 |
边的值不在范围内 |
√ |
5 |
101 |
101 |
101 |
A-B-C-M-O |
边的值不在范围内 |
边的值不在范围内 |
√ |
6 |
102 |
102 |
102 |
A-B-C-M-O |
边的值不在范围内 |
边的值不在范围内 |
√ |
7 |
101 |
99 |
99 |
A-B-C-M-O |
边的值不在范围内 |
边的值不在范围内 |
√ |
8 |
2 |
3 |
5 |
A-B-C-D-L |
不构成三角形 |
不构成三角形 |
√ |
9 |
2 |
2 |
3 |
A-B-C-D-E-H |
等腰三角形 |
等腰三角形 |
√ |
10 |
3 |
4 |
3 |
A-B-C-D-E-H |
等腰三角形 |
等腰三角形 |
√ |
11 |
3 |
4 |
5 |
A-B-C-D-E-G-I-J |
直角三角形 |
直角三角形 |
√ |
12 |
5 |
4 |
3 |
A-B-C-D-E-G-I-J |
直角三角形 |
直角三角形 |
√ |
13 |
3 |
5 |
4 |
A-B-C-D-E-G-I-J |
直角三角形 |
直角三角形 |
√ |
14 |
5 |
4 |
7 |
A-B-C-D-E-G-I-K |
普通三角形 |
普通三角形 |
√ |
|
|
|
|
|
3)相应Junit测试脚本、执行结果
脚本:
package test03; import static org.junit.Assert.*; import org.junit.Before; import org.junit.Test; public class TriangleTest { Triangle tr = new Triangle(); @Before public void setUp() throws Exception { System.out.println("开始测试"); } @Test public void test_Dengbian01() { assertEquals("等边三角形",tr.triangle(1, 1, 1)); } @Test public void test_ValueNotin01() { assertEquals("边的值不在范围内",tr.triangle(-1, -1, -1)); } @Test public void test_ValueNotin02() { assertEquals("边的值不在范围内",tr.triangle(0, 0, 0)); } @Test public void test_ValueNotin03() { assertEquals("边的值不在范围内",tr.triangle(101, 101, 101)); } @Test public void test_ValueNotin04() { assertEquals("边的值不在范围内",tr.triangle(102, 102, 102)); } @Test public void test_ValueNotin05() { assertEquals("边的值不在范围内",tr.triangle(101, 99, 99)); } @Test public void test_NotMakeR01() { assertEquals("边的值不在范围内",tr.triangle(2, 3, 5)); } @Test public void test_DengYao01() { assertEquals("等腰三角形",tr.triangle(2, 2, 3)); } @Test public void test_DengYao02() { assertEquals("等腰三角形",tr.triangle(3, 4, 3)); } @Test public void test_ZhiJiao01() { assertEquals("直角三角形",tr.triangle(3, 4, 5)); } @Test public void test_ZhiJiao02() { assertEquals("直角三角形",tr.triangle(3, 5, 4)); } @Test public void test_ZhiJiao03() { assertEquals("直角三角形",tr.triangle(5, 4, 3)); } @Test public void test_PuTong01() { assertEquals("直角三角形",tr.triangle(5, 4, 7)); } }
4)给出测试参数化和打包测试的脚本,并生成执行结果
由于被测试代码中所写的方法triangle(int a,int b,int c)返回值为void,所以影响到了我的单元测试的正常进行。
执行结果:以上脚本运行报错。
4、测试小结:
测试样例都成功通过。
修改建议:由于被测试代码中所写的方法triangle(int a,int b,int c)返回值为void,所以影响到了我的单元测试的正常进行。建议重新根据实验要求编写triangle(int a,int b,int c)返回值改为为String型。
感受:Junit无法对返回值是void类型的方法进行测试,因为Junit的assert断言方法只适用于预期值与实际值的比较,对于void类型的方法,我们无法从它的return语句获得具体的返回值。
建议老师在本次实验前要求程序员对上次代码存在的问题进行修改。