软件质量与测试报告3-功能测试 JUnit与覆盖测试 EclEmma
目录
不要问学长图为什么这么糊,问就是学长也是从别人那截图来的(图被截过多次,自然糊了),课太水了,一言难尽。差不多得了,90分太伤身体,85分就够了。
一、 要求和目的
本实验中,要求学生独立完成下面的内容:
1) 学习并掌握 JUnit 的使用方法;
2) 学习并掌握 EclEmma 的使用方法。
二、 环境和设备
本实验中需要:同前一个实验。
三、 内容与步骤
A. 日期推算器
请下载日期推算器程序(ST.emma.dayDiff),完成下列任务:
1) 请对程序中的两个 Java 文件进行注释,特别是类和方法都需要注释;
①对于Day.java的注释如下:
②对于DayDiff.java的注释如下:
2) 通过用 EclEmma 来执行 DayDiff 类,查看其代码覆盖情况;
3) 通过扩展 DayOff 的 main 函数来提高代码的覆盖率,要求至少两个类的覆盖率均达
到 90%以上;
4) 请将 main 函数记录到实验报告上。
/**
* 主方法,用于测试 compute 方法
*/
public static void main(String[] args) {
DayDiff dd = new DayDiff();
// 测试用例 1: 正常情况下减去天数
System.out.println(dd.compute(2015, 4, 8, -10)); // 输出 2015-3-29
// 测试用例 2: 正常情况下加上天数
System.out.println(dd.compute(2015, 4, 8, 10)); // 输出 2015-4-18
// 测试用例 3: 跨年前加上天数
System.out.println(dd.compute(2015, 12, 25, 10)); // 输出 2016-1-4
// 测试用例 4: 跨年后减去天数
System.out.println(dd.compute(2016, 1, 5, -10)); // 输出 2015-12-26
// 测试用例 5: 加上大量天数,跨越多个年份
System.out.println(dd.compute(2015, 1, 1, 800)); // 输出 2017-3-11
// 测试用例 6: 减去大量天数,跨越多个年份
System.out.println(dd.compute(2017, 3, 11, -800)); // 输出 2015-1-1
// 测试用例 7: 在闰年中操作
System.out.println(dd.compute(2020, 2, 29, 1)); // 输出 2020-3-1
// 测试用例 8: 从闰年跨到非闰年
System.out.println(dd.compute(2020, 2, 28, 1)); // 输出 2020-2-29
// 测试用例 9: 非闰年中的2月
System.out.println(dd.compute(2021, 2, 28, 1)); // 输出 2021-3-1
// 测试用例 10: 加上0天
System.out.println(dd.compute(2021, 6, 15, 0)); // 输出 2021-6-15
// 错误1
System.out.println(dd.compute(2024, 2, 30, 5)); // 2024年2月没有30号
// 错误2
System.out.println(dd.compute(2024, 13, 15, 5));// 月份超出了合法范围
// 错误3
System.out.println(dd.compute(2023, 2, 29, 5));// 2023年不是闰年,无法有2月29日
// 错误4
System.out.println(dd.compute(2024, 1, 0, 5));// 日期为零
}
程序存在的问题:
无法正确处理边界条件,对于不合法的输入没有进行校验。
B. 售货机程序
请编写实现一个售货机程序,其基本工作原理如下:
1) 该售货机提供 beer 和 orange 两种饮料,每种饮料的价格都是 50 分;
2) 两种饮料的初始库存都是 3,售货机内存有 50 分(5 角)硬币5 个和 100 分(1 元) 硬币 3 个;
3) 用户通过投币和选择饮料类型实现自动购物,其中:
●硬币仅支持 50 分或 100 分 1 枚,其他硬币值不接受,否则提示“请投 5 角或者1 元的硬币。”;
●如果用户选择了超出了 beer 和orange 的饮料,提示“目前不提供该饮料。”;
●如果用户投入 50 分硬币,选择的饮料正好有库存,提示“请取饮料”,否则已经 售完则提示“目前该饮料已经售完。”;
●如果用户投入 100 分硬币,在上一种情况的基础上,还需检查是否机内存有 50 分硬币,如有则提示“请取饮料,并取回找钱。”,否则提示“对不起,目前不能 找钱,请投 5 角硬币。”;
●特别注意:上述描述仅为基本功能,其他相关操作需要独立思考并程序实现,比 如:提示“请取饮料”还需将该饮料库存减少一;等等。
4) 请在 Eclipse 新建一个 SaleMachine 项目,并新建一个 SaleMachine 类,该类中有一 个方法:
public String buy(String type, int money);
其中 type 表示饮料类型,仅支持 beer 和 orange;money 是投币金额,仅支持 50 和 100; 返回值是显示的信息。
因果图如下:
5) 请编写 main 方法,自行测试程序,确保自己对程序功能满意,请将源程序记录到 实验报告中。
// 售货机
public class SaleMachine {
// 饮料库存
private int beerStock = 3;
private int orangeStock = 3;
// 硬币库存
private int fiftyCentsCoins = 5;
private int oneDollarCoins = 3;
/**
* 用户购买饮料的方法
* @param type 饮料类型,仅支持 beer 和 orange
* @param money 投币金额,仅支持 50 和 100
* @return 返回操作结果的信息
*/
public String buy(String type, int money) {
// 检查投币金额是否正确
if (money != 50 && money != 100) {
return "请投 5 角或者 1 元的硬币。";
}
// 检查饮料类型是否正确
if (!type.equals("beer") && !type.equals("orange")) {
return "目前不提供该饮料。";
}
// 处理购买逻辑
if (type.equals("beer")) {
if (beerStock == 0) {
return "目前该饮料已经售完。";
} else if (money == 50) {
beerStock--;
fiftyCentsCoins++;
return "请取饮料";
} else if (money == 100) {
if (fiftyCentsCoins == 0) {
return "对不起,目前不能找钱,请投 5 角硬币。";
} else {
beerStock--;
oneDollarCoins++;
fiftyCentsCoins--;
return "请取饮料,并取回找钱。";
}
}
} else if (type.equals("orange")) {
if (orangeStock == 0) {
return "目前该饮料已经售完。";
} else if (money == 50) {
orangeStock--;
fiftyCentsCoins++;
return "请取饮料";
} else if (money == 100) {
if (fiftyCentsCoins == 0) {
return "对不起,目前不能找钱,请投 5 角硬币。";
} else {
orangeStock--;
oneDollarCoins++;
fiftyCentsCoins--;
return "请取饮料,并取回找钱。";
}
}
}
return "未知错误。";
}
// 测试主方法
public static void main(String[] args) {
SaleMachine sm = new SaleMachine();
// 测试用例
System.out.println(sm.buy("beer", 50)); // 应输出:请取饮料
System.out.println(sm.buy("orange", 50)); // 应输出:请取饮料
System.out.println(sm.buy("beer", 100)); // 应输出:请取饮料,并取回找钱。
System.out.println(sm.buy("orange", 100)); // 应输出:请取饮料,并取回找钱。
System.out.println(sm.buy("beer", 100)); // 应输出:请取饮料,并取回找钱。
System.out.println(sm.buy("beer", 50)); // 应输出:请取饮料
System.out.println(sm.buy("beer", 50)); // 应输出:目前该饮料已经售完。
System.out.println(sm.buy("beer", 100)); // 应输出:目前该饮料已经售完。
System.out.println(sm.buy("orange", 100)); // 应输出:请取饮料,并取回找钱。
System.out.println(sm.buy("orange", 100)); // 应输出:请取饮料,并取回找钱。
System.out.println(sm.buy("orange", 50)); // 应输出:请取饮料
System.out.println(sm.buy("orange", 50)); // 应输出:目前该饮料已经售完。
System.out.println(sm.buy("orange", 100)); // 应输出:目前该饮料已经售完。
System.out.println(sm.buy("coke", 50)); // 应输出:目前不提供该饮料。
System.out.println(sm.buy("beer", 10)); // 应输出:请投 5 角或者 1 元的硬币。
}
}
6) 用 JUnit 测试售货机程序,步骤如下:
●请建立 SaleMachineTest 类,内容如下:
import static org.junit.Assert.assertEquals;
import org.junit.Test;
public class SaleMachineTest {
//pick 4 beers one by one with 50 coin,
//the message should be three times "ok" //and "failed" at the last time;
@Test public void test_50Beer(){
SaleMachinesm = new SaleMachine();
assertEquals(sm.buy("beer", 50), "请取饮料"); assertEquals(sm.buy("beer", 50), "请取饮料"); assertEquals(sm.buy("beer", 50), "请取饮料");
assertEquals(sm.buy("beer", 50), "目前该饮料已经售完。");
}
}
●点击“@Test public void test_50Beer()”行前错误标识处,添加 JUnit4 支持;
●运行这个测试类;
●运行结果应该如下图所示,否则请仔细检查程序;
●请参照“test50Beer()”编写下列测试方法:
投币 1 元购买橙汁四次;
投币 1 元购买橙汁三次,然后投币 1 元购买啤酒三次。
●用 EclEmma 进行覆盖测试,请设计新的测试用例以期尽可能的扩大整个项目的覆盖率, 要求整个工程的覆盖率至少达到 80% ,请将测试方法和测试结果记录在试验报告上。
①覆盖率
②测试结果
③测试方法
import static org.junit.Assert.assertEquals;
import org.junit.Test;
public class SaleMachineTest {
// 投币 50 分购买啤酒四次,前三次应该成功,第四次提示售完
@Test
public void test_50Beer() {
SaleMachine sm = new SaleMachine();
assertEquals("请取饮料", sm.buy("beer", 50));
assertEquals("请取饮料", sm.buy("beer", 50));
assertEquals("请取饮料", sm.buy("beer", 50));
assertEquals("目前该饮料已经售完。", sm.buy("beer", 50));
}
// 投币 1 元购买橙汁四次,前三次应该成功并找零,第四次提示售完
@Test
public void test_100Orange() {
SaleMachine sm = new SaleMachine();
assertEquals("请取饮料,并取回找钱。", sm.buy("orange", 100));
assertEquals("请取饮料,并取回找钱。", sm.buy("orange", 100));
assertEquals("请取饮料,并取回找钱。", sm.buy("orange", 100));
assertEquals("目前该饮料已经售完。", sm.buy("orange", 100));
}
// 投币 1 元购买橙汁三次,投币 1 元购买啤酒三次,前三次橙汁应该成功并找零
// 第一次啤酒应成功并找零,后两次啤酒无法找零
@Test
public void test_100OrangeThen100Beer() {
SaleMachine sm = new SaleMachine();
assertEquals("请取饮料,并取回找钱。", sm.buy("orange", 100));
assertEquals("请取饮料,并取回找钱。", sm.buy("orange", 100));
assertEquals("请取饮料,并取回找钱。", sm.buy("orange", 100));
assertEquals("请取饮料,并取回找钱。", sm.buy("beer", 100));
assertEquals("请取饮料,并取回找钱。", sm.buy("beer", 100));
assertEquals("对不起,目前不能找钱,请投 5 角硬币。", sm.buy("beer", 100));
}
// 投币金额不正确的情况
@Test
public void test_invalidCoin() {
SaleMachine sm = new SaleMachine();
assertEquals("请投 5 角或者 1 元的硬币。", sm.buy("beer", 25));
assertEquals("请投 5 角或者 1 元的硬币。", sm.buy("orange", 75));
}
// 选择不存在的饮料类型
@Test
public void test_invalidDrink() {
SaleMachine sm = new SaleMachine();
assertEquals("目前不提供该饮料。", sm.buy("coke", 50));
assertEquals("目前不提供该饮料。", sm.buy("water", 100));
}
// 测试库存和硬币数量上限情况
@Test
public void test_maximumCapacity() {
SaleMachine sm = new SaleMachine();
for (int i = 0; i < 100; i++) {
sm.buy("beer", 100);
sm.buy("orange", 100);
}
assertEquals("目前该饮料已经售完。", sm.buy("beer", 100)); // 库存已达上限
assertEquals("对不起,目前不能找钱,请投 5 角硬币。", sm.buy("orange", 100)); // 50 分硬币用完
}
// 测试连续购买啤酒超出库存的情况
@Test
public void test_exceedBeerStock() {
SaleMachine sm = new SaleMachine();
assertEquals("请取饮料,并取回找钱。", sm.buy("beer", 100));
assertEquals("请取饮料", sm.buy("beer", 50));
assertEquals("请取饮料", sm.buy("beer", 50));
assertEquals("目前该饮料已经售完。", sm.buy("beer", 50));
assertEquals("目前该饮料已经售完。", sm.buy("beer", 50)); // 库存已用完
}
// 测试连续购买橙汁超出库存的情况
@Test
public void test_exceedOrangeStock() {
SaleMachine sm = new SaleMachine();
assertEquals("请取饮料,并取回找钱。", sm.buy("orange", 100));
assertEquals("请取饮料", sm.buy("orange", 50));
assertEquals("请取饮料", sm.buy("orange", 50));
assertEquals("目前该饮料已经售完。", sm.buy("orange", 50));
assertEquals("目前该饮料已经售完。", sm.buy("orange", 50)); // 库存已用完
}
}
原文地址:https://blog.csdn.net/qq_71654538/article/details/145316929
免责声明:本站文章内容转载自网络资源,如侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!