Java黑盒测试之nextDate函数测试
作者:Starzkg 发布时间:2023-02-10 20:31:08
一、实验目的
(1)掌握应用黑盒测试技术进行测试用例设计。
(2)掌握对测试用例进行优化设计方法。
二、实验内容
日期问题
测试以下程序:该程序有三个输入变量month、day、year(month、day和year均为整数值,并且满足:1≤month≤12、1≤day≤31和1900≤year≤2050),分别作为输入日期的月份、日、年份,通过程序可以输出该输入日期在日历上隔一天的日期。例如,输入为2004 年11月30日,则该程序的输出为2004年12月1日。
(1)划分等价类,按照等价类划分法设计测试用例;
(2)编写nextDate函数;
(3)掌握Junit4的用法,使用Junit4测试nextDate函数。
JUnit4是JUnit框架有史以来的最大改进,其主要目标便是利用Java5的Annotation特性简化测试用例的编写。
掌握Junit4定义的一些常见Annotations:
org.junit.Test
org.junit.Before
org.junit.After
org.junit.BeforeClass
org.junit.AfterClass
org.junit.Ignore
org.junit.runner.RunWith
org.junit.runners.Suite.SuiteClasses
org.junit.runners.Parameterized.Parameters
三、实验要求
(1)根据题目要求编写测试用例;
(2)准备nextDate函数,使用Junit4测试执行测试;
(3)撰写实验报告。
四、实验过程
(1)根据题目要求编写测试用例
1)划分等价类并编号
输入数据 | 有效等价类 | 无效等价类 |
年 | (1) 1900到2050内的闰年整数 | (10) year<1900 |
(2) 1900到2050内的平年整数 | (11) year>2050 | |
(12) 其他输入 | ||
月 | (3) 1,3,5,7,8,10,12内的整数 | (13) month<1 |
(4) 4,6,9,11内的整数 | (14) 12<month | |
(5) 2 | (15) 其他输入 | |
日 | (6) 1~28 | (16) day<1 |
(7) 29 | (17) year为闰年 month=2时,29<day | |
(8) 30 | (18) year为非闰年 month=2时,28<day | |
(9) 31 | (19) month=1,3,5,7,8,10,12时,31<day | |
(20) month=4,6,9,11时,30<day | ||
(21) day>31 | ||
(22) 其他输入 |
2)为有效等价类设计测试用例
序号 | 测试数据 | 期望结果 | 覆盖范围 |
1 | 2016 2 29 | 下一天是2016年3月1日! | (1)(5)(7) |
2 | 2017 1 28 | 下一天是2017年1月29日! | (2)(3)(6) |
3 | 2017 1 31 | 下一天是2017年2月1日! | (2)(3)(9) |
4 | 2017 4 30 | 下一天是2017年5月1日! | (2)(4)(8) |
5 | 2017 12 31 | 下一天是2018年1月1日! | (2)(3)(9) |
3)为每一个无效等价类至少设计一个测试用例
序号 | 输入数据 | 期望结果 | 覆盖范围 |
6 | 1899 3 1 | 年的值不在指定范围之内 | (10) |
7 | 2051 3 1 | 年的值不在指定范围之内 | (11) |
8 | 205% 3 1 | 无效的输入日期! | (12) |
9 | 1901 -1 1 | 月的值不在指定范围之内 | (13) |
10 | 1901 13 1 | 月的值不在指定范围之内 | (14) |
11 | 1901 1% 1 | 无效的输入日期! | (15) |
12 | 1901 1 -1 | 日的值不在指定范围之内 | (16) |
13 | 2016 2 30 | 日的值不在指定范围之内 | (17) |
14 | 2017 2 29 | 日的值不在指定范围之内 | (18) |
15 | 2017 3 32 | 日的值不在指定范围之内 | (19) |
16 | 2017 4 31 | 日的值不在指定范围之内 | (20) |
17 | 2017 4 32 | 日的值不在指定范围之内 | (21) |
18 | 2017 4 3% | 无效的输入日期! | (22) |
(2)编写nextDate函数,使用Junit4测试执行测试
被测代码
package io.shentuzhigang.demo.blackbox;
import java.util.regex.Pattern;
/**
* @author ShenTuZhiGang
* @version 1.0.0
* @date 2021-05-06 15:43
*/
public class Date {
private static final Pattern pattern = Pattern.compile("^[-\\+]?[\\d]*$");
public static String nextDate(String s_year, String s_month, String s_day) {
//检测是否存在无效字符
if (!(isInteger(s_year) && isInteger(s_month) && isInteger(s_day))) {
return "无效的输入日期!";
}
//将字符串转为int
int year = Integer.parseInt(s_year);
int month = Integer.parseInt(s_month);
int day = Integer.parseInt((s_day));
boolean flag = false;
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 + "日!");
}
}
/**
* 判断输入字符串是否是整数型
*
* @param str
* @return
*/
public static boolean isInteger(String str) {
return pattern.matcher(str).matches();
}
}
测试代码
package io.shentuzhigang.demo.blackbox;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import java.util.Arrays;
import java.util.Collection;
/**
* @author ShenTuZhiGang
* @version 1.0.0
* @date 2021-05-06 15:43
*/
@RunWith(Parameterized.class)
public class DateTests {
private String input1;
private String input2;
private String input3;
private String expected;
@Parameters
public static Collection<?> prepareData(){
String [][] object = {
// 有效等价类
{"2016","2","29","下一天是2016年3月1日!"},
{"2017","1","28","下一天是2017年1月29日!"},
{"2017","1","31","下一天是2017年2月1日!"},
{"2017","4","30","下一天是2017年5月1日!"},
// 无效等价类
{"1899","3","1","年的值不在指定范围之内"},
{"2051","3","1","年的值不在指定范围之内"},
{"205%","3","1","无效的输入日期!"},
{"1901","-1","1","月的值不在指定范围之内"},
{"1901","13","1","月的值不在指定范围之内"},
{"1901","1%","1","无效的输入日期!"},
{"1901","1","-1","日的值不在指定范围之内"},
{"2016","2","30","日的值不在指定范围之内"},
{"2017","2","29","日的值不在指定范围之内"},
{"2017","3","32","日的值不在指定范围之内"},
{"2017","4","31","日的值不在指定范围之内"},
{"2017","4","32","日的值不在指定范围之内"},
{"2017","4","3%","无效的输入日期!"}
};
return Arrays.asList(object);
}
public DateTests(String input1,String input2,String input3,String expected){
this.input1 = input1;
this.input2 = input2;
this.input3 = input3;
this.expected = expected;
}
@Test
public void testDate(){
String result = Date.nextDate(input1,input2,input3);
Assert.assertEquals(expected,result);
}
}
测试结果
五、缺陷分析
1.用例?发生故障的原因是程序先判断day为29就变为3月1日,而不先判断是否为闰年,于是用例?的输出结果为2007-3-1而不是无效输入日期。
2.用例?发生故障的原因是程序没有先判断接收的三个参数是否在指定范围内,而是先根据month进行数据处理,再判断处理后的参数是否在指定范围内,用例?的参数因为month为3所以直接day+1由0变成1再判断day在指定范围内,所以用例?的输出结果为1998-3-1而不是日的值不在指定范围内。
来源:https://blog.csdn.net/weixin_43272781/article/details/116454710


猜你喜欢
- 项目需要对接外部接口,将图片文件流发送到外部接口,下面代码就是HttpsURLConnection如何上传文件流:/** *
- resultMap的Colum和property属性1: resultMap标签当我们的数据库字段与实体类的属性不一致时,就需要使用该标签进
- 根据UGUI的射线检测机制获取当前鼠标下的UI:/// <summary> /// 获取鼠标停留处UI
- 偶然发现有小伙伴错误地使用了Collections.emptyList()方法,这里记录一下。她的使用方式是:public void run
- 本文实例讲述了Android编程基于重力传感器实现横竖屏放向切换功能。分享给大家供大家参考,具体如下:最近项目中用到了vr视频播放,因为自己
- 目录前言I. 字符串转列表1. jdk支持方式2. guava方式3. apache-commonsII. 列表转字符串1. StringB
- 使用Android AudioRecord 录制PCM文件,android SDK保证在所有设备上都支持的采样频率只有44100HZ,所以如
- class MyThreadScopeData { // 单例 &nbs
- 概述java.lang.String 类代表字符串。Java程序中所有的字符串文字(例如"abc" )都可以被看作是实现
- 本文实例展示了Activiti流程图查看的实现方法,具体步骤如下所示:1、测试用例查看图片代码如下:public void viewImag
- Rxjava功能个人感觉很好用,里面的一些操作符很方便,Rxjava有:被观察者,观察者,订阅者,被观察者通过订阅者订阅观察者,从而实现观察
- 一、引入其实之前一直以为像饿了么或者是美团外卖那种把商品添加到购物车的动画会很难做,但是实际做起来好像并没有想象中的那么难哈哈。布局主要使用
- 本文实例讲述了Android编程实现图片放大缩小功能ZoomControls控件用法。分享给大家供大家参考,具体如下:MainActivit
- 1. 前言现在很多应用都有小悬浮窗的功能,比如看直播的时候,通过Home键返回桌面,直播的小窗口仍可以在屏幕上显示。下面将介绍下悬浮窗的的一
- 0. Iochttps://docs.spring.io/spring-framework/docs/current/spring-fram
- 一、Container 简介flutter 开发中最核心的是用最少的组件(层次)完成功能开发;Container 前端的盒子模型实现,类似
- 本文实现初次设置密码验证过程,首先实现如下效果布局如下:<?xml version="1.0" encoding=
- 匿名内部类:先举个例子吧,给大家看一下什么是匿名内部类,Endeavor刚刚接触的时候,觉得哇哦,好奇怪的样子,这也太别扭了吧,不知道大家是
- 本文实例讲述了Android编程出现Button点击事件无效的解决方法。分享给大家供大家参考,具体如下:遇到这样一个问题,给一个界面上方的按
- Handler是用于操作线程内部的消息队列的类。这有点绕,没关系,我们慢慢的来讲。前面Looper一篇讲到了Looper是用于给线程创建消息