软件质量与测试报告3-功能测试 JUnit与覆盖测试 EclEmma

ops/2025/2/5 7:47:00/

目录

一、 要求和目的

二、 环境和设备

三、 内容与步骤

A.   日期推算器

B.  售货机程序


不要问学长图为什么这么糊,问就是学长也是从别人那截图来的(图被截过多次,自然糊了),课太水了,一言难尽。差不多得了,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// 错误1System.out.println(dd.compute(2024, 2, 30, 5)); // 2024年2月没有30号// 错误2System.out.println(dd.compute(2024, 13, 15, 5));// 月份超出了合法范围// 错误3System.out.println(dd.compute(2023, 2, 29, 5));// 2023年不是闰年,无法有2月29日// 错误4System.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 分购买啤酒四次,前三次应该成功,第四次提示售完@Testpublic 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 元购买橙汁四次,前三次应该成功并找零,第四次提示售完@Testpublic 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 元购买啤酒三次,前三次橙汁应该成功并找零// 第一次啤酒应成功并找零,后两次啤酒无法找零@Testpublic 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));}// 投币金额不正确的情况@Testpublic void test_invalidCoin() {SaleMachine sm = new SaleMachine();assertEquals("请投 5 角或者 1 元的硬币。", sm.buy("beer", 25));assertEquals("请投 5 角或者 1 元的硬币。", sm.buy("orange", 75));}// 选择不存在的饮料类型@Testpublic void test_invalidDrink() {SaleMachine sm = new SaleMachine();assertEquals("目前不提供该饮料。", sm.buy("coke", 50));assertEquals("目前不提供该饮料。", sm.buy("water", 100));}// 测试库存和硬币数量上限情况@Testpublic 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 分硬币用完}// 测试连续购买啤酒超出库存的情况@Testpublic 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)); // 库存已用完}// 测试连续购买橙汁超出库存的情况@Testpublic 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)); // 库存已用完}
}

http://www.ppmy.cn/ops/155812.html

相关文章

CTF从入门到精通

文章目录 背景知识CTF赛制 背景知识 CTF赛制 1.web安全:通过浏览器访问题目服务器上的网站&#xff0c;寻找网站漏洞(sql注入&#xff0c;xss&#xff08;钓鱼链接&#xff09;,文件上传&#xff0c;包含漏洞&#xff0c;xxe&#xff0c;ssrf&#xff0c;命令执行&#xff0c…

使用 Iptables 实现网络安全策略:从入门到精通

使用 Iptables 实现网络安全策略:从入门到精通 在运维工作中,网络安全是重中之重,而 iptables 作为 Linux 内核自带的防火墙工具,提供了强大的流量控制能力。通过合理的 iptables 规则,我们可以有效防止未经授权的访问,保护服务器免受攻击。今天,我们就来深入探讨如何使…

MyBatis-Plus速成指南:基本CURD

BaseMapper&#xff1a; MyBatis-Plus 中的基本 CURD 在内置的 BaseMapper 中都已得到了实现&#xff0c;我们可以直接使用接口&#xff0c;接口如下&#xff1a; // // Source code recreated from a .class file by IntelliJ IDEA // (powered by FernFlower decompiler) //p…

使用Pytorch训练一个图像分类器

一、准备数据集 一般来说&#xff0c;当你不得不与图像、文本或者视频资料打交道时&#xff0c;会选择使用python的标准库将原始数据加载转化成numpy数组&#xff0c;甚至可以继续转换成torch.*Tensor。 对图片而言&#xff0c;可以使用Pillow库和OpenCV库对视频而言&#xf…

python学习笔记5-函数的定义

1.函数的定义&#xff1a; # def 是英⽂ define 的缩写def 函数名&#xff08;[参数1],[参数2]....[参数n]&#xff09;:函数体 关于函数名的定义&#xff0c;有几项需要注意的地方&#xff1a; • 函数名命名规则同变量名&#xff0c;要满⾜标识符命名规则 • 不能和系统…

3 Flink 运行架构

3 Flink 运行架构 1. Flink 程序结构2. Flink 并行数据流3. Task 和 Operator chain4. 任务调度与执行5. 任务槽和槽共享 1. Flink 程序结构 Flink 程序的基本构建块是流和转换&#xff08;请注意&#xff0c;Flink 的 DataSet API 中使用的 DataSet 也是内部流 &#xff09;。…

开发板上Qt运行的环境变量的三条设置语句的详解

在终端中运行下面三句命令用于配置开发板上Qt运行的环境变量&#xff1a; export QT_QPA_GENERIC_PLUGINStslib:/dev/input/event1 export QT_QPA_PLATFORMlinuxfb:fb/dev/fb0 export QT_QPA_FONTDIR/usr/lib/fonts/设置成功后可以用下面的语句检查设置成功没有 echo $QT_QPA…

Block Blaster Online:免费解谜游戏的乐趣

Block Blaster Online 是一款免费的在线解谜游戏&#xff0c;它将挑战你的思维和反应能力&#xff01;在这里&#xff0c;你可以匹配五彩缤纷的方块&#xff0c;创造出令人惊叹的组合&#xff0c;享受无尽的解谜乐趣。无需安装&#xff0c;点击即可开始&#xff0c;加入全球数百…