实验二+124+高小娟
一、实验目的
掌握基于覆盖理论与基本路径的基本白盒测试方法和实践
二、实验要求
运用逻辑覆盖测试的覆盖准则设计被测程序的测试用例,并运行测试用例检查程序的正确与否,给出程序缺陷小结。
三、实验内容
(1) 被测原代码
1 package 软件测试实验1; 2 import java.util.Scanner; 3 4 public class NextDate { 5 //nextdate函数 6 public static String nextdate(int month,int day,int year){ 7 int isleap[]={31,29,31,30,31,30,31,31,30,31,30,31}; 8 int noleap[]={31,28,31,30,31,30,31,31,30,31,30,31}; 9 int m,d,y; 10 11 if (month<1 || month>12){ 12 return "月份超出范围"; 13 } 14 if (day<1 || day>31){ 15 return "日期超出范围"; 16 } 17 if (year<1912 || year>2050){ 18 return "年份超出范围"; 19 } 20 if ((year%4==0 && year%100!=0) || year%400==0){//闰年 21 if (day<isleap[month-1]){ 22 d = day+1; 23 m = month; 24 y = year; 25 } 26 else if (day==isleap[month-1]){//该月的最后一天 27 d=1; 28 if (month==12){//一年的最后一天 29 m = 1; 30 y = year+1; 31 } 32 else{ 33 m = month+1; 34 y = year; 35 } 36 } 37 else{//针对31天以内,但是超出该月最大天数 38 return "日期超出范围"; 39 } 40 } 41 else{//非闰年 42 if (day<noleap[month-1]){ 43 d = day+1; 44 m = month; 45 y = year; 46 } 47 else if (day==noleap[month-1]){//该月的最后一天 48 d = 1; 49 if (month==12){//一年的最后一天 50 m = 1; 51 y = year+1; 52 } 53 else{ 54 m = month+1; 55 y = year; 56 } 57 } 58 else{//针对31天以内,但是超出该月最大天数 59 return "日期超出范围"; 60 } 61 } 62 return y + "年" + m + "月" + d + "日"; 63 } 64 65 public static void main(String[] args) { 66 67 while(true){ 68 69 System.out.println("1、请输入日期(格式:月 日 年)"); 70 System.out.println("2、退出"); 71 System.out.println("请输入序号 :"); 72 Scanner scan = new Scanner(System.in); 73 String num = scan.next(); 74 if(num.equals("1")){ 75 if(scan.hasNextInt()){ 76 int m = scan.nextInt(); 77 int d = scan.nextInt(); 78 int y = scan.nextInt(); 79 System.out.println(nextdate(m,d,y)); 80 } 81 else{ 82 System.out.println("输入格式错误!!!"); 83 } 84 } 85 else if(num.equals("2")){ 86 scan.close(); 87 System.out.println("谢谢使用!"); 88 break; 89 } 90 } 91 92 } 93 }
(2)依据覆盖技术,测试用例列表
a.程序图:
b.DD-路径图:
DD-路径(只压缩链路经)
程序图节点 |
DD-路径 |
6 |
A |
11 |
B |
12 |
C |
14 |
D |
15 |
E |
17 |
F |
18 |
G |
20 |
H |
21 |
I |
22,23,24 |
J |
26 |
K |
27,28 |
L |
29,30 |
M |
32,33,34 |
N |
37,38 |
O |
41,42 |
P |
43,44,45 |
Q |
47 |
R |
48,49 |
S |
50,51 |
T |
53,54,55 |
U |
58,59 |
V |
62 |
W |
63 |
X |
c.测试用例表:
(I)语句覆盖:
A—B—C—X
A—B—D—E—X
A—B—D—F—G—X
A—B—D—F—H—I—J—W—X
A—B—D—F—H—I—K—L—M—W—X
A—B—D—F—H—I—K—L—N—W—X
A—B—D—F—H—I—K—O—X
A—B—D—F—H—P—Q—W—X
A—B—D—F—H—P—R—S—T—W—X
A—B—D—F—H—P—R—S—U—W—X
A—B—D—F—H—P—R—V—W—X
测试用例:
用例ID |
输入值 |
执行路径 |
预期输出 |
实际输出 |
||
月 |
日 |
年 |
|
|
|
|
U01 |
-1 |
7 |
2009 |
A—B—C—X |
月份超出范围 |
月份超出范围 |
U02 |
5 |
32 |
2009 |
A—B—D—E—X |
日期超出范围 |
日期超出范围 |
U03 |
5 |
7 |
1911 |
A—B—D—F—G—X |
年份超出范围 |
年份超出范围 |
U04 |
2 |
28 |
2008 |
A—B—D—F—H—I—J—W—X |
2008年2月29日 |
2008年2月29日 |
U05 |
12 |
31 |
2008 |
A—B—D—F—H—I—K—L—M—W—X |
2009年1月1日 |
2009年1月1日 |
U06 |
2 |
29 |
2008 |
A—B—D—F—H—I—K—L—N—W—X |
2008年3月1日 |
2008年3月1日 |
U07 |
2 |
30 |
2008 |
A—B—D—F—H—I—K—O—X |
日期超出范围 |
日期超出范围 |
U08 |
5 |
5 |
2009 |
A—B—D—F—H—P—Q—W—X |
2009年5月6日 |
2009年5月6日 |
U09 |
12 |
31 |
2009 |
A—B—D—F—H—P—R—S—T—W—X |
2010年1月1日 |
2010年1月1日 |
U10 |
2 |
28 |
2009 |
A—B—D—F—H—P—R—S—U—W—X |
2009年3月1日 |
2009年3月1日 |
U11 |
2 |
29 |
2009 |
A—B—D—F—H—P—R—V—W—X |
日期超出范围 |
日期超出范围 |
(II)分支覆盖(判断覆盖):
A—B—C—X (左)
A—B—D—E—X (右—左)
A—B—D—F—G—X (右—右—左)
A—B—D—F—H—I—J—W—X (右—右—右—左—左)
A—B—D—F—H—I—K—L—M—W—X (右—右—右—左—右—左—左)
A—B—D—F—H—I—K—L—N—W—X (右—右—右—左—右—左—右)
A—B—D—F—H—I—K—O—X (右—右—右—左—右—右)
A—B—D—F—H—P—Q—W—X (右—右—右—右—左)
A—B—D—F—H—P—R—S—T—W—X (右—右—右—右—右—左—左)
A—B—D—F—H—P—R—S—U—W—X (右—右—右—右—右—左—右)
A—B—D—F—H—P—R—V—W—X (右—右—右—右—右—右)
测试用例:
用例ID |
输入值 |
执行路径 |
预期输出 |
实际输出 |
||
月 |
日 |
年 |
|
|
|
|
U01 |
-1 |
7 |
2009 |
A—B—C—X |
月份超出范围 |
月份超出范围 |
U02 |
5 |
32 |
2009 |
A—B—D—E—X |
日期超出范围 |
日期超出范围 |
U03 |
5 |
7 |
1911 |
A—B—D—F—G—X |
年份超出范围 |
年份超出范围 |
U04 |
2 |
28 |
2008 |
A—B—D—F—H—I—J—W—X |
2008年2月29日 |
2008年2月29日 |
U05 |
12 |
31 |
2008 |
A—B—D—F—H—I—K—L—M—W—X |
2009年1月1日 |
2009年1月1日 |
U06 |
2 |
29 |
2008 |
A—B—D—F—H—I—K—L—N—W—X |
2008年3月1日 |
2008年3月1日 |
U07 |
2 |
30 |
2008 |
A—B—D—F—H—I—K—O—X |
日期超出范围 |
日期超出范围 |
U08 |
5 |
5 |
2009 |
A—B—D—F—H—P—Q—W—X |
2009年5月6日 |
2009年5月6日 |
U09 |
12 |
31 |
2009 |
A—B—D—F—H—P—R—S—T—W—X |
2010年1月1日 |
2010年1月1日 |
U10 |
2 |
28 |
2009 |
A—B—D—F—H—P—R—S—U—W—X |
2009年3月1日 |
2009年3月1日 |
U11 |
2 |
29 |
2009 |
A—B—D—F—H—P—R—V—W—X |
日期超出范围 |
日期超出范围 |
(III)路径覆盖:
A—B—C—X (左)
A—B—D—E—X (右—左)
A—B—D—F—G—X (右—右—左)
A—B—D—F—H—I—J—W—X (右—右—右—左—左)
A—B—D—F—H—I—K—L—M—W—X (右—右—右—左—右—左—左)
A—B—D—F—H—I—K—L—N—W—X (右—右—右—左—右—左—右)
A—B—D—F—H—I—K—O—X (右—右—右—左—右—右)
A—B—D—F—H—P—Q—W—X (右—右—右—右—左)
A—B—D—F—H—P—R—S—T—W—X (右—右—右—右—右—左—左)
A—B—D—F—H—P—R—S—U—W—X (右—右—右—右—右—左—右)
A—B—D—F—H—P—R—V—W—X (右—右—右—右—右—右)
测试用例:
用例ID |
输入值 |
执行路径 |
预期输出 |
实际输出 |
||
月 |
日 |
年 |
|
|
|
|
U01 |
-1 |
7 |
2009 |
A—B—C—X |
月份超出范围 |
月份超出范围 |
U02 |
5 |
32 |
2009 |
A—B—D—E—X |
日期超出范围 |
日期超出范围 |
U03 |
5 |
7 |
1911 |
A—B—D—F—G—X |
年份超出范围 |
年份超出范围 |
U04 |
2 |
28 |
2008 |
A—B—D—F—H—I—J—W—X |
2008年2月29日 |
2008年2月29日 |
U05 |
12 |
31 |
2008 |
A—B—D—F—H—I—K—L—M—W—X |
2009年1月1日 |
2009年1月1日 |
U06 |
2 |
29 |
2008 |
A—B—D—F—H—I—K—L—N—W—X |
2008年3月1日 |
2008年3月1日 |
U07 |
2 |
30 |
2008 |
A—B—D—F—H—I—K—O—X |
日期超出范围 |
日期超出范围 |
U08 |
5 |
5 |
2009 |
A—B—D—F—H—P—Q—W—X |
2009年5月6日 |
2009年5月6日 |
U09 |
12 |
31 |
2009 |
A—B—D—F—H—P—R—S—T—W—X |
2010年1月1日 |
2010年1月1日 |
U10 |
2 |
28 |
2009 |
A—B—D—F—H—P—R—S—U—W—X |
2009年3月1日 |
2009年3月1日 |
U11 |
2 |
29 |
2009 |
A—B—D—F—H—P—R—V—W—X |
日期超出范围 |
日期超出范围 |
(IV)条件覆盖:各个条件取真或假的可能至少执行一次
编号 |
month<1 |
month>12 |
(month<1)||(month>12) |
覆盖路径 |
1 |
T |
F |
T |
B—C |
2 |
F |
T |
T |
B—C |
3 |
F |
F |
F |
B—D |
编号 |
day<1 |
day>31 |
(day<1)||(day>31) |
覆盖路径 |
4 |
T |
F |
T |
B—D—E |
5 |
F |
T |
T |
B—D—E |
6 |
F |
F |
F |
B—D—F |
编号 |
year<1912 |
year>2051 |
(year<1912)||(year>2050) |
覆盖路径 |
7 |
T |
F |
T |
B—D—F—G |
8 |
F |
T |
T |
B—D—F—G |
9 |
F |
F |
F |
B—D—F—H |
编号 |
year%4==0 |
year%100!=0 |
year%400==0 |
(year%4==0&&year%100!=0)||(year%400==0) |
覆盖路径 |
10 |
T |
T |
T |
T |
B—D—F—H—I |
12 |
T |
F |
T |
T |
B—D—F—H—I |
11 |
F |
T |
F |
F |
B—D—F—H—P |
闰年的日期判断:
编号 |
day<isleap[month-1] |
覆盖路径 |
13 |
T |
B—D—F—H—I—J |
14 |
F |
B—D—F—H—I—K |
编号 |
day==isleap[month-1] |
覆盖路径 |
13 |
T |
B—D—F—H—I—K—L |
14 |
F |
B—D—F—H—I—K—O |
编号 |
month==12 |
覆盖路径 |
13 |
T |
B—D—F—H—I—K—L—M |
14 |
F |
B—D—F—H—I—K—O—N |
非闰年的日期判断:
编号 |
day<isleap[month-1] |
覆盖路径 |
15 |
T |
B—D—F—H—P—Q |
16 |
F |
B—D—F—H—P—R |
编号 |
day==isleap[month-1] |
覆盖路径 |
17 |
T |
B—D—F—H—P—R—S |
18 |
F |
B—D—F—H—I—R—V |
编号 |
month==12 |
覆盖路径 |
13 |
T |
B—D—F—H—P—R—S—T |
14 |
F |
B—D—F—H—P—R—S—V |
测试用例:
用例ID |
输入值 |
执行路径 |
预期输出 |
实际输出 |
||
月 |
日 |
年 |
|
|
|
|
U01 |
-1 |
7 |
2009 |
A—B—C—X |
月份超出范围 |
月份超出范围 |
U02 |
5 |
32 |
2009 |
A—B—D—E—X |
日期超出范围 |
日期超出范围 |
U03 |
5 |
7 |
1911 |
A—B—D—F—G—X |
年份超出范围 |
年份超出范围 |
U04 |
2 |
28 |
2008 |
A—B—D—F—H—I—J—W—X |
2008年2月29日 |
2008年2月29日 |
U05 |
12 |
31 |
2008 |
A—B—D—F—H—I—K—L—M—W—X |
2009年1月1日 |
2009年1月1日 |
U06 |
2 |
29 |
2008 |
A—B—D—F—H—I—K—L—N—W—X |
2008年3月1日 |
2008年3月1日 |
U07 |
2 |
30 |
2008 |
A—B—D—F—H—I—K—O—X |
日期超出范围 |
日期超出范围 |
U08 |
5 |
5 |
2009 |
A—B—D—F—H—P—Q—W—X |
2009年5月6日 |
2009年5月6日 |
U09 |
12 |
31 |
2009 |
A—B—D—F—H—P—R—S—T—W—X |
2010年1月1日 |
2010年1月1日 |
U10 |
2 |
28 |
2009 |
A—B—D—F—H—P—R—S—U—W—X |
2009年3月1日 |
2009年3月1日 |
U11 |
2 |
29 |
2009 |
A—B—D—F—H—P—R—V—W—X |
日期超出范围 |
日期超出范围 |
(3)相应Junit测试脚本、执行结果:
1 package 软件测试实验1; 2 3 import static org.junit.Assert.*; 4 5 import org.junit.Before; 6 import org.junit.Test; 7 8 public class NextDateTest { 9 10 @Before 11 public void setUp() throws Exception { 12 } 13 14 //语句覆盖Statement Coverage 15 @Test 16 public void testStatementNextdate1(){ 17 String date=NextDate.nextdate(-1,7,2009); 18 assertEquals("月份超出范围",date); 19 } 20 @Test 21 public void testStatementNextdate2(){ 22 String date=NextDate.nextdate(5,32,2009); 23 assertEquals("日期超出范围",date); 24 } 25 @Test 26 public void testStatementNextdate3(){ 27 String date=NextDate.nextdate(5,7,1911); 28 assertEquals("年份超出范围",date); 29 } 30 //分支覆盖:Brach Coverage 31 @Test 32 public void testBrachNextdate1(){ 33 String date=NextDate.nextdate(2,28,2008); 34 assertEquals("2008年2月29日",date); 35 } 36 @Test 37 public void testBrachNextdate2(){ 38 String date=NextDate.nextdate(2,29,2008); 39 assertEquals("2008年3月1日",date); 40 } 41 @Test 42 public void testBrachNextdate3(){ 43 String date=NextDate.nextdate(2,28,2009); 44 assertEquals("2009年3月1日",date); 45 } 46 //路径覆盖:Path Coverage 47 @Test 48 public void testPathNextdate1(){ 49 String date=NextDate.nextdate(12,31,2008); 50 assertEquals("2009年1月1日",date); 51 } 52 @Test 53 public void testPathNextdate2(){ 54 String date=NextDate.nextdate(12,31,2009); 55 assertEquals("2010年1月1日",date); 56 } 57 @Test 58 public void testPathNextdate3(){ 59 String date=NextDate.nextdate(2,29,2009); 60 assertEquals("日期超出范围",date); 61 } 62 //条件覆盖:Condition Coverage 63 @Test 64 public void testConditionNextdate1(){ 65 String date=NextDate.nextdate(2,29,2009); 66 assertEquals("日期超出范围",date); 67 } 68 @Test 69 public void testConditionNextdate2(){ 70 String date=NextDate.nextdate(5,5,2008); 71 assertEquals("2008年5月6日",date); 72 } 73 74 }
Junit执行结果:
(4)测试小结:
a.到目前为止,程序通过了所有的测试;由于Nextday需要对年份(闰年、非闰年)的判断,所以在对语句:(year%4==0&&year%100!=0)||(year%400==0)进行条件覆盖的时候,就要考虑较多的情况,需要编写较多的测试用例;
b.通过本次实验我加深了对覆盖理论与基本路径的基本白盒测试方法和实践的理解;
c.之前在Junit中,我把所有的测试都写在一个函数里,并且命名也比较随意;听了老师的建议:(1)一个测试用例一个函数,(2)函数名:test+覆盖方法+测试方法名,这样能确保测试结果的准确性,也能使函数名看起来直观。