一、实验目的
(1)掌握覆盖理论和应用
(2)掌握路径覆盖测试的基本方法
二、实验要求
(1)完成各个程序的编写(例如三角形程序、LastData、NextData和佣金问题)
(2)运用逻辑覆盖测试的覆盖准则设计被测程序的测试用例,并运行测试用例检查程序的正确与否
(3)要求根据源程序画出程序流程图、写出测试用例和测试脚本。
三、实验内容
案例:设计某程序的路径覆盖测试用例,如语句覆盖路径覆盖、条件覆盖、分支覆盖等
伪代码程序如下:
一、
1.三角形程序:
public class sjiao {
private int A, B, C;
public sJiao(int a, int b, int c) {
A = a;
B = b;
C = c;
}
public String isJiao() {
String s = "三角形吗";
if (A <= 0 || B <= 0 || C <= 0) {
s = "边长不能为负数和零";
} else if (A >= B + C || B > A + C || C >= A + B) {
s = "不是三角形";
} else {
if (A == B && C == B) {
s = "是等边三角形";
return s;
} else {
if (A * A + B * B == C * C || A * A + C * C == B * B || B * B + C * C == A * A) { if (A == B || B == C || C == A) {
s = "是等腰直角三角形";
}else{
s = "是直角三角形";
return s;
} else {
if (A == B || B == C || C == A) {
s = "是等腰三角形";
return s;
} else {
s = "是不规则三角形";
return s;
}
}
}
}
return s;
}
}
2.程序流程图:
3.独立路径:
1:a->b->c
2:a->b->d->e
3:a->b->d->f->y
4:a->b->d->f->n->g
5:a->b->d->f->n->h->Y
6:a->b->d->f->n->h->i
7:a->b->d->f->n->m->z
- 设计测试用例
路径覆盖:
测试用例序号 | 输入数据 | 预期输出 | 测试路径 |
01 | 1,2,3 | 不是三角形 | 2 |
02 | 3,3,4 | 是等腰三角形 | 4 |
03 | 3,4,5 | 是直角三角形 | 5 |
04 | 1,1,2**1/2 | 是等腰直角三角形 | 7 |
06 | 3,3,3 | 是等边三角形 | 3 |
07 | 3,6,5 | 是不规则三角形 | 6 |
08 | 0,2,3 | 边长不能为负数和0 | 1 |
09 | -1,2,3 | 边长不能为负数和0 | 1 |
语句覆盖:
测试用例序号 | 输入数据 | 预期输出 | 测试路径 |
02 | 3,3,4 | 是等腰三角形 | 4 |
03 | 3,4,5 | 是直角三角形 | 5 |
04 | 1,1,2**1/2 | 是等腰直角三角形 | 7 |
06 | 3,3,3 | 是等边三角形 | 3 |
07 | 3,6,5 | 是不规则三角形 | 6 |
分支覆盖:
序号 | 输入数据 | 预期输出 | 测试路径 |
01 | 1,2,3 | 不是三角形 | bde |
02 | 0,2,3 | 边长不能为负数和0 | bc |
03 | 3,3,3 | 是等边三角形 | bdfy |
04 | 1,1,2**1/2 | 是等腰直角三角形 | bdfnmz |
05 | 3,4,5 | 是直角三角形 | bdfnhY |
06 | 3,3,4 | 是等腰三角形 | bdfng |
07 | 3,6,5 | 是不规则三角形 | bdfnhi |
条件覆盖:
序号 | 输入数据 | 输出数据 | 路径 |
01 | 0,0,0[f,f,f] | 边长不能为负数和0 | bc |
02 | 3,6,5 | 是不规则三角形 | bdfnhi |
5.测试代码及运行结果:
import org.junit.Test;
import static org.junit.Assert.*;
public class sJiaoTest {
@Test
public void isJiao() {
assertEquals("不是三角形", new sJiao(1, 2, 3).isJiao());
assertEquals("是等腰三角形", new sJiao(3, 3, 4).isJiao());
assertEquals("是等腰等腰三角形", new sJiao(1, 1, 2**1/2).isJiao());
assertEquals("是直角三角形", new sJiao(3, 4, 5).isJiao());
assertEquals("是等边三角形", new sJiao(3, 3, 3).isJiao());
assertEquals("是不规则三角形", new sJiao(3, 6, 5).isJiao());
assertEquals("边长不能为负数和0", new sJiao(0, 2, 3).isJiao());
assertEquals("边长不能为负数和0", new sJiao(-1, 2, 3).isJiao());
}
}
运行结果:
二、Lastday
二、
1.LastData程序代码:
public class LastData {
private int year,month,day;
public LastData(int Y, int M, int D) {
year=Y;
month=M;
day=D;
}
boolean flag = false;
public String lastData() {
if (year<=0 || month<=0 || day<=0) {
return "无效的输入日期!";
}if (year < 1900 || year > 2050) {
return "年的值不在指定范围之内";
} else if (month > 12 || month < 1) {
return ("月的值不在指定范围之内");
} else if (day > 31 || day < 1) {
return ("日的值不在指定范围之内");
}
switch (month) {
case 12://31天的月份
case 5:
case 7:
case 8:
case 10:
if (day == 1) {
day = 30;
month = month - 1;
} else
day = day - 1;
break;
case 4:
case 6:
case 9:
case 11:
if (day == 1) {
day = 31;
month = month - 1;
} else if (day == 31) {
flag = true;
} else
day = day - 1;
break;
case 1:
if (day == 1) {
day = 31;
month = 12;
year = year - 1;
} else {
day = day - 1;
}
break;
case 3:{
if (((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)) {
// 闰年29
if (day == 1) {
day = 29;
month = 2;
} else if (day < 31) {
day = day - 1;
} else {
flag = true; // day超过29
}
} else {
//平年28
if (day == 1) {
day = 28;
month = 2;
} else if (day < 31) {
day = day - 1;
} else {
flag = true;
}
}
}
break;
case 2: {
if (((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)) {
// 闰年29
if (day == 1) {
day = 31;
month = 1;
} else if (day < 30) {
day = day - 1;
} else {
flag = true; // day超过29
}
} else {
//平年28
if (day == 1) {
day = 31;
month = 1;
} else if (day < 29) {
day = day - 1;
} else {
flag = true;
}
}
}
break;
default:
}
if (year > 2100) {
return ("年的值不在指定范围之内");
} else if (flag) {
return ("日的值不在指定范围之内");
} else {
return ("上一天是" + year + "年" + month + "月" + day + "日!");
}
}
}
2.程序流程图:
3.独立路径:
1:a->b->c[无效日期]
2: a->b->d->e[年不在指定范围之内]
3:a->b->d->e1->f[月不在指定范围之内]
4:a->b->d->e1->f1->j[日不在指定范围之内]
5:a->b->d->e1->f1->j1->g->g1[12,5,7,8,10的第一天]
6:a->b->d->e1->f1->j1->g->g2->n[12,5,7,8,10的普通日子]
7:a->b->d->e1->f1->j1->h->m[2,4,6,9,11的第一天]
8:a->b->d->e1->f1->j1->h->n[2,4,6,9,11月的普通日子]
9:a->b->d->e1->f1->j1->z->z1[闰年3月第一天]
10:a->b->d->e1->f1->j1->z->z2[平年3月第一天]
11:a->b->d->e1->f1->j1->z->z3->n[3月普通日子]
12:a->b->d->e1->f1->j1->i->i1[1月第一天]
13:a->b->d->e1->f1->j1->i->i2->n[1月普通日子]
4.设计测试用例:
路径覆盖:
测试用例序号 | 输入数据 | 预期结果 | 路径 |
01 | 0,0,0 | 无效日期 | 1 |
02 | 2200,11,15 | 年不在指定范围之内! | 2 |
03 | 2022,13,13 | 月不在指定范围之内! | 3 |
04 | 2022,11,32 | 日不在指定范围之内! | 4 |
05 | 2022,11,15 | 上一天是2022年11月14日! | 5 |
06 | 2022,1,1 | 上一天是2021年12月31日! | 12 |
07 | 2022,3,1 | 上一天是2022年2月28日! | 10 |
08 | 2020,3,1 | 上一天是2019年2月29日! | 9 |
09 | 2022,1,2 | 上一天是2022年1月1日! | 13 |
10 | 2022,12,2 | 上一天是2022年12月1日! | 6 |
11 | 2021,3,1 | 上一天是2021年2月28日! | 10 |
12 | 2020,3,1 | 上一天是2020年2月29日! | 11 |
13 | 2022,2,1 | 上一天是2022年1月31日! | 7 |
14 | 2022,2,3 | 上一天是2022年2月2日! | 8 |
语句覆盖:
测试用例序号 | 输入数据 | 预期结果 | 路径 |
01 | 2022,2,1 | 上一天是2022年1月31日! | 7 |
02 | 2022,2,3 | 上一天是2022年2月2日! | 8 |
03 | 2021,3,1 | 上一天是2021年2月28日! | 10 |
04 | 2020,3,1 | 上一天是2020年2月29日! | 11 |
05 | 2022,12,2 | 上一天是2022年12月1日! | 6 |
06 | 0,0,0 | 无效日期 | 1 |
07 | 2200,11,15 | 年不在指定范围之内! | 2 |
08 | 2022,13,13 | 月不在指定范围之内! | 3 |
09 | 2022,11,32 | 日不在指定范围之内! | 4 |
分支覆盖:
测试用例序号 | 输入数据 | 预期结果 | 路径 |
01 | 0,0,0 | 无效日期 | 1 |
02 | 2200,11,15 | 年不在指定范围之内! | 2 |
03 | 2022,13,13 | 月不在指定范围之内! | 3 |
04 | 2022,11,32 | 日不在指定范围之内! | 4 |
05 | 2022,3,1 | 上一天是2022年2月28日! | 10 |
06 | 2020,3,1 | 上一天是2019年2月29日! | 9 |
07 | 2022,2,1 | 上一天是2022年1月31日! | 7 |
08 | 2022,2,3 | 上一天是2022年2月2日! | 8 |
条件覆盖:
测试用例序号 | 输入数据 | 预期结果 | 路径 |
01 | 0,0,0 | 无效日期 | 1 |
02 | 2020,3,1 | 上一天是2022年2月29日! | 10 |
03 | 2022,12,2 | 上一天是2022年12月1日! | 6 |
04 | 2022,11,15 | 上一天是2022年11月14日! | 5 |
测试代码及运行结果:
5.测试代码及运行结果:
public class LastDataTest {
@Test
public void lastData() {
assertEquals("无效的输入日期!", new NextData(0, 0, 0).nextData());
assertEquals("年的值不在指定范围之内", new NextData(2200, 11, 13).nextData());
assertEquals("月的值不在指定范围之内", new NextData(2022, 13, 13).nextData());
assertEquals("日的值不在指定范围之内", new NextData(2022, 11, 32).nextData());
assertEquals("上一天是2022年11月14日!", new LastData(2022, 11, 15).lastData());
assertEquals("上一天是2022年1月1日!", new LastData(2022, 1, 2).lastData());
assertEquals("上一天是2022年2月28日!", new LastData(2022, 3, 1).lastData());
assertEquals("上一天是2021年2月28日!", new LastData(2021, 3, 1).lastData());
assertEquals("上一天是2000年2月29日!", new LastData(2000, 3, 1).lastData());
assertEquals("上一天是2032年2月29日!", new LastData(2032, 3, 1).lastData());
assertEquals("上一天是2020年2月29日!", new LastData(2020, 3, 1).lastData());
}
}
三、NextDay:
1.NextData程序代码:
输入年月日year month day
其中年份的有效取值范围为【1900,2050】,请输出日期的下一天
import java.util.regex.Pattern;
public class NextData {
private int year,month,day;
public NextData(int Y, int M, int D) {
year=Y;
month=M;
day=D;
}
boolean flag = false;
//检测是否存在无效字符
public String nextData() {
if (year<0 || month<0 || day<=0) {
return "无效的输入日期!";
}if (year < 1900 || year > 2050) {
return "年的值不在指定范围之内";
} else if (month > 12 || month < 1) {
return ("月的值不在指定范围之内");
} else if (day > 31 || day < 1) {
return ("日的值不在指定范围之内");
}
switch (month) {
case 1:
case 3:
case 5:
case 7:
case 8:
case 10:
if (day == 31) {
day = 1;
month = month + 1;
} else
day = day + 1;
break;
case 4:
case 6:
case 9:
case 11:
if (day == 30) {
day = 1;
month = month + 1;
} else if (day == 31) {
flag = true;
} else
day = day + 1;
break;
case 12:
if (day == 31) {
day = 1;
month = 1;
year = year + 1;
} else {
day = day + 1;
} break;
case 2: {
if (((year % 4 == 0 && year % 100 != 0) || year % 400 == 0)) {
// 闰年
if (day == 29) {
day = 1;
month = 3;
} else if (day < 29) {
day = day + 1;
} else {
flag = true; // day超过29
}
} else {
//非闰年
if (day == 28) {
day = 1;
month = 3;
} else if (day < 28) {
day = day + 1;
} else {
flag = true;
}
}
}=break;
default:
}
if (year > 2050) {
return ("年的值不在指定范围之内");
} else if (flag) {
return ("日的值不在指定范围之内");
} else {
return ("下一天是" + year + "年" + month + "月" + day + "日!");
}
}
}
2.基本流程图:
3.独立路径:
1:a->b->c[无效日期]
2: a->b->d->e[年不在指定范围之内]
3:a->b->d->e1->f[月不在指定范围之内]
4:a->b->d->e1->f1->j[日不在指定范围之内]
5:a->b->d->e1->f1->j1->g->g1[1,3,5,7,8,10的最后]
6:a->b->d->e1->f1->j1->g->g2->n,[1,3,5,7,8,10的普通日子]
7:a->b->d->e1->f1->j1->h->m[4,6,9,11的最后一天]
8:a->b->d->e1->f1->j1->h->n[4,6,9,11月的普通日子]
9:a->b->d->e1->f1->j1->z->z1[闰年2月最后一天]
10:a->b->d->e1->f1->j1->z->z2[平年2月最后一天]
11:a->b->d->e1->f1->j1->z->z3->n[闰年2月普通日子]
12:a->b->d->e1->f1->j1->z->z2->n[闰年2月普通日子]
13:a->b->d->e1->f1->j1->i->i1[12月最后一天]
14:a->b->d->e1->f1->j1->i->i2->n[12月普通日子]
4.设计测试用例:
路径覆盖:
测试用例序号 | 输入数据 | 预期结果 | 路径 |
01 | 0,0,0 | 无效日期 | 1 |
02 | 2200,11,15 | 年不在指定范围之内! | 2 |
03 | 2022,13,13 | 月不在指定范围之内! | 3 |
04 | 2022,11,32 | 日不在指定范围之内! | 4 |
05 | 2022,11,13 | 下一天是2022年11月14日! | 8 |
06 | 2022,12,31 | 下一天是2021年1月1日! | 13 |
07 | 2022,2,28 | 下一天是2022年3月1日! | 10 |
08 | 2020,2,29 | 下一天是2019年3月1日! | 9 |
09 | 2022,1,2 | 下一天是2022年1月3日! | 6 |
10 | 2022,12,2 | 下一天是2022年12月3日! | 14 |
11 | 2021,3,1 | 下一天是2021年3月2日! | 6 |
12 | 2017,2,29 | 日的值不在指定范围之内! | 4 |
13 | 2022.1.31 | 下一天是2022年2月1日! | 5 |
14 | 2022.4.30 | 下一天是2022年5月1日 | 7 |
语句覆盖:
序号 | 输入数据 | 输出数据 | 路径 |
01 | 2022,11,13 | 下一天是2022年11月14日! | 8 |
02 | 2022,12,31 | 下一天是2021年1月1日! | 13 |
03 | 2020,2,29 | 下一天是2019年3月1日! | 9 |
04 | 2022,1,2 | 下一天是2022年1月3日! | 6 |
05 | 0,0,0 | 无效日期 | 1 |
06 | 2200,11,15 | 年不在指定范围之内! | 2 |
07 | 2022,13,13 | 月不在指定范围之内! | 3 |
08 | 2022,11,32 | 日不在指定范围之内! | 4 |
分支覆盖:
测试用例序号 | 输入数据 | 预期结果 | 路径 |
01 | 0,0,0 | 无效日期 | 1 |
02 | 2200,11,15 | 年不在指定范围之内! | 2 |
03 | 2022,13,13 | 月不在指定范围之内! | 3 |
04 | 2022,11,32 | 日不在指定范围之内! | 4 |
05 | 2022,12,31 | 下一天是2021年1月1日! | 13 |
06 | 2022,2,28 | 下一天是2022年3月1日! | 10 |
07 | 2020,2,29 | 下一天是2019年3月1日! | 9 |
08 | 2021,3,1 | 下一天是2021年3月2日! | 6 |
09 | 2022.4.30 | 下一天是2022年5月1日 | 7 |
条件覆盖:
序号 | 输入数据 | 输出数据 | 路径 |
01 | 2022,11,13 | 下一天是2022年11月14日! | 8 |
02 | 2022,12,31 | 下一天是2021年1月1日! | 13 |
03 | 2020,2,29 | 下一天是2019年3月1日! | 9 |
04 | 2022,1,2 | 下一天是2022年1月3日! | 6 |
01 | 0,0,0 | 无效日期 | 1 |
5.测试代码:
import org.junit.Test;
import static org.junit.Assert.*;
public class NextDataTest {
@Test
public void nextData() {
assertEquals("无效的输入日期!", new NextData(0, 0, 0).nextData());
assertEquals("年的值不在指定范围之内", new NextData(2200, 11, 13).nextData());
assertEquals("月的值不在指定范围之内", new NextData(2022, 13, 13).nextData());
assertEquals("日的值不在指定范围之内", new NextData(2022, 11, 32).nextData());
assertEquals("下一天是2022年11月14日!", new NextData(2022, 11, 13).nextData());
assertEquals("下一天是2022年1月1日!", new NextData(2022, 12, 31).nextData());
assertEquals("下一天是2022年3月1日!", new NextData(2022, 2, 28).nextData());
assertEquals("下一天是2020年3月1日!", new NextData(2022, 2, 29).nextData());
assertEquals("日的值不在指定范围之内", new NextData(2022, 2, 30).nextData());
assertEquals("无效的输入日期!", new NextData(2022, -11, 13).nextData());
assertEquals("无效的输入日期!", new NextData(2022, 11, -13).nextData());
assertEquals("年的值不在指定范围之内", new NextData(1022, 11, 13).nextData());
assertEquals("日的值不在指定范围之内", new NextData(2017, 2, 29).nextData());
}
}
测试结果:
四、佣金问题等价类测试用例,它是根据佣金函数的输出值域定义等价类,来改进测试用例集合。
输出销售额≤1000元 佣金10%
1000<销售额≤1800 佣金=100+(销售额-1000)*15%
销售额>1800 佣金=220+(销售额-1800)*20%
根据输出域选择输入值,使落在输出域等价类内,可以结合弱健壮测试用例结合。
前亚利桑那洲境内的一位步枪销售商销售密苏里州制造商制造的步枪机(lock)、枪托(stock)和枪管(barrel)。枪机卖45美元,枪托卖30美元,枪管卖25美元。销售商每月至少要售出一支完整的步枪,且生产限额是大多数销售商在一个月内可销售70个枪机、80个枪托和90个枪管。
1.佣金问题程序代码:
1.佣金问题程序代码:
import java.util.Scanner;
public class yongJin {
private double lockprice = 45;
private double stockprice = 30;
private double barrelprice = 25;
private int locks;
private int stocks;
private int barrels;
private double totallocks = 0;
private double totalstocks = 0;
private double totalbarrels = 0;
private double commission;
public yongJin(int totallocks, int totalstocks, int totalbarrels) {
locks = totallocks;
stocks = totalstocks;
barrels = totalbarrels;
}
public String yongjin() {
if (locks == -1 || stocks == -1 || barrels == -1) {
return "当月销售活动结束!";
}
if (1 > locks || locks > 70) {
return "对不起,枪机数不能为负数且⼚商限制⼀个月只能卖出少于70个!";
} else if (1 >= stocks || stocks >= 80) {
return "对不起,枪托数不能为负数且⼚商限制⼀个月只能卖出少于80个!";
} else if (1 >= barrels || barrels >= 90) {
return "对不起,枪管数不能为负数且⼚商限制⼀个月只能卖出少于90个!";
} else {
totallocks = totallocks + locks;
totalstocks = totalstocks + stocks;
totalbarrels = totalbarrels + barrels;
double locksales = lockprice * totallocks;
double stocksales = stockprice * totalstocks;
double barrelsales = barrelprice * totalbarrels;
double sales = locksales + stocksales + barrelsales;
//double commission;
if (sales > 1800) {
commission = 0.10 * 1000;
commission = commission + 0.15 * 800;
commission = commission + 0.20 * (sales - 1800);
} else if (sales > 1000) {
commission = 0.10 * 1000;
commission = commission + 0.15 * (sales - 1000);
return "commission is $:" + commission;
} else {
commission = 0.10 * sales;
return "commission is $:" + commission;
}
}
return "commission is $:" + commission;
}
}
2.测试流程图:
3.独立路径:
1:a->b->c->u[某类售空]
2:a->b->d->g->u[枪机情况不符]
3:a->b->d->y->u[枪托情况不符]
4:a->b->d->f->u[枪管情况不符]
5:a->b->d->hik(o)->q->t->u[1800以上]
6:a->b->d->hik(o)->p->t->u[1000到含1800]
7:a->b->d->hik(o)->s->t->u[1000及以下]
4.设计测试用例:
路径覆盖:
测试用例序号 | 输入数据 | 预期结果 | 路径 |
01 | -1,-2,-2 | 当月销售活动结束 | 1 |
02 | 5,5,5 | 50.0 | 7 |
03 | 15,15,15 | 175.0 | 6 |
04 | 25,25,25 | 360.0 | 5 |
05 | 75,5,5 | 对不起,枪机数不能为负数且⼚商限制⼀个月只能卖出少于70个! | 2 |
06 | 25,5,85 | 对不起,枪托数不能为负数且⼚商限制⼀个月只能卖出少于80个! | 3 |
07 | 5,5,95 | 对不起,枪管数不能为负数且⼚商限制⼀个月只能卖出少于90个! | 4 |
语句覆盖:
测试用例序号 | 输入数据 | 预期结果 | 路径 |
01 | -1,-2,-2 | 当月销售活动结束 | 1 |
05 | 75,5,5 | 对不起,枪机数不能为负数且⼚商限制⼀个月只能卖出少于70个! | 2 |
06 | 25,5,85 | 对不起,枪托数不能为负数且⼚商限制⼀个月只能卖出少于80个! | 3 |
07 | 5,5,95 | 对不起,枪管数不能为负数且⼚商限制⼀个月只能卖出少于90个! | 4 |
分支覆盖:
测试用例序号 | 输入数据 | 预期结果 | 路径 |
01 | -1,-2,-2 | 当月销售活动结束 | 1 |
02 | 75,5,5 | 对不起,枪机数不能为负数且⼚商限制⼀个月只能卖出少于70个! | 2 |
03 | 25,5,85 | 对不起,枪托数不能为负数且⼚商限制⼀个月只能卖出少于80个! | 3 |
04 | 5,5,95 | 对不起,枪管数不能为负数且⼚商限制⼀个月只能卖出少于90个! | 4 |
05 | 25,25,25 | 360.0 | 5 |
条件覆盖:
测试用例序号 | 输入数据 | 预期结果 | 路径 |
01 | -1,-2,-2 | 当月销售活动结束 | 1 |
02 | 25,25,25 | 360.0 | 5 |
5.测试代码及结果:
5.测试代码及结果:
import org.junit.Test;
import static org.junit.Assert.*;
public class yongJinTest {
@Test
public void yongjin() {
assertEquals("当月销售活动结束!", new yongJin(-1,-2,-2).yongjin());
assertEquals("commission is $:50.0", new yongJin(5,5,5).yongjin());
assertEquals("commission is $:175.0", new yongJin(15,15,15).yongjin());
assertEquals("commission is $:360.0", new yongJin(25,25,25).yongjin());
assertEquals("对不起,枪机数不能为负数且⼚商限制⼀个月只能卖出少于70个!", new yongJin(75,5,5).yongjin());
assertEquals("对不起,枪托数不能为负数且⼚商限制⼀个月只能卖出少于80个!", new yongJin(15,85,15).yongjin());
assertEquals("对不起,枪管数不能为负数且⼚商限制⼀个月只能卖出少于90个!", new yongJin(25,25,95).yongjin());
}
}