《软件工程》实验报告——软件测试
一、实验目的
掌握结构化分析与设计方法
掌握JUnit的用法;
掌握白盒测试中路径覆盖的测试用例设计;
掌握黑盒测试中等价类方法;
二、实验内容
1. 某证券公司为了方便提供证券交易服务,欲开发一证券交易平台。该平台接收客户命令信息,可执行以下主要功能:
(1)登录。输入用户名、密码及校验码信息,登录证券交易平台。
(2)开户。如果是新客户,需先提交开户信息,进行开户,并将客户信息存入客户记录中,账户信息(余额等)存入账户记录中;
(3)存款。客户可以向其账户中存款,根据存款金额修改账户余额;
(4)取款。客户可以从其账户中取款,根据取款金额修改账户余额;
(5)证券交易。客户进行证券交易,将交易信息存入交易记录中;
(6)查询交易。平台从交易记录中读取交易信息,将交易明细返回给客户。。
该平台采用结构化分析方法,画出第1层的数据流图如下图所示(有简化):
判断该信息流属于变换流还是事务流,并将该数据流图映射为程序结构,画出程序结构图。
事务流
2. 进行测试驱动的开发
测试驱动开发,英文全称Test-Driven Development,简称TDD,是一种不同于传统软件开发流程的新型的开发方法。它要求在编写某个功能的代码之前先编写测试代码,然后只编写使测试通过的功能代码,通过测试来推动整个开发的进行。这有助于编写简洁可用和高质量的代码,并加速开发过程。
测试驱动开发过程可分为:1)分析需求;2)设计测试用例;3)开发测试代码;4)开发功能代码;5)运行测试,据此修改代码,直到全部通过。
本实验要求按照测试驱动的开发的过程进行一个类的开发。已提供一个类Point2d的源代码。要求编写另一个类Rect,通过左上角点和宽度、高度定义一个长方形(认为它的边分别平行于x和y轴)。要求该类具备:
1)无参构造方法,默认左上角点在(0,0),宽度、高度均为1。
2)单参数构造方法,接收Point2d参数作为左上角点。宽度、高度默认为1。
3)三参数构造方法,接收Point2d参数及两个double值,分别设置其左上角点与宽度、高度。
4)能够计算长方形面积。
5)能够判断某个点是位于长方形内(含在边上)、或其外。
为此,可按照以下步骤进行开发:
1)建立一个空的Rect类;
2)右键点击Rect类,选择NewàJunit Test Case,在对话模式选择:
建立一个测试用例RectCreationTest,用于测试Rect的构造方法。
3)第一个测试可写成:
@Testpublic void test() {Rect r = new Rect();assertNotEquals(p, null);Point2d p = r.getTopleft();assertEquals(r.getWidth(), 1.0, 1.0e-6);assertEquals(r.getHeight(), 1.0, 1.0e-6);}
即用于测试无参构造方法所得对象,默认左上角点在(0,0),宽度、高度均为1。
4)运行测试,Run AsàJunit Test,不通过。
5)开发功能代码,即写上无参构造方法。
6)再次运行测试,直至通过。至此可保证无参构造方法已编写完毕。
按照上述过程,将上面要求的其余5项功能按照测试驱动开发的方式编写完成。
Point2d类
package io.shentuzhigang.demo.design.tdo;/*** @author ShenTuZhiGang* @version 1.0.0* @date 2020-12-24 13:40*/public class Point2d {private double x;private double y;public Point2d(){this(0, 0);}public Point2d(double x, double y){this.x = x;this.y = y;}public double getX() {return x;}public void setX(double x) {this.x = x;}public double getY() {return y;}public void setY(double y) {this.y = y;}}
Rect类
package io.shentuzhigang.demo.design.tdo;/*** @author ShenTuZhiGang* @version 1.0.0* @date 2020-12-24 13:41*/ public class Rect {private Point2d topLeftPoint;private int width;private int height;public Rect() {this(new Point2d(0,0),1,1);}public Rect(Point2d topLeftPoint) {this(topLeftPoint,1,1);}public Rect(Point2d topLeftPoint, int weight, int height) {this.topLeftPoint = topLeftPoint;this.width = weight;this.height = height;}public double area(){return width * height;}public boolean contain(Point2d point){return topLeftPoint.getX()<=point.getX() && point.getX()<=topLeftPoint.getX()+ width&& topLeftPoint.getY()<=point.getY() && point.getY()<=topLeftPoint.getY()+height;}public Point2d getTopLeftPoint() {return topLeftPoint;}public void setTopLeftPoint(Point2d topLeftPoint) {this.topLeftPoint = topLeftPoint;}public int getWidth() {return width;}public void setWidth(int width) {this.width = width;}public int getHeight() {return height;}public void setHeight(int height) {this.height = height;} }
RectCreationTest类
package io.shentuzhigang.demo.design.tdo;import org.junit.jupiter.api.Test;import static org.junit.jupiter.api.Assertions.*;/*** @author ShenTuZhiGang* @version 1.0.0* @date 2020-12-24 13:51*/ public class RectCreationTest {@Testpublic void test() {Rect r = new Rect();assertNotEquals(r, null);Point2d p = r.getTopLeftPoint();assertEquals(r.getWidth(), 1.0, 1.0e-6);assertEquals(r.getHeight(), 1.0, 1.0e-6);}}
3. 有以下程序(其中的操作并没有什么具体意义,仅用于演示)
基于JUnit,针对以下程序设计测试用例,满足路径覆盖标准。
import java.awt.Point;
public class Path {public static Point Coverage(int a, int b, int c){Point p = new Point();int x = 5;int y = 7;if(a>b && b>c){a += 1;x += 6;if(a==10 || b>20){b += 1;x = y+4; }if(a<10 || c==20){b += 2;y = 4;}a = a + b + 1;y = x + y;}if(a>5 || c<10){b = c + 5;x += 1;}p.x = x;p.y = y;return p;}
}
自行画出程序流图,如教材P329。计算独立路径数量,进而设计基本路径测试所需的测试用例:
序号 |
测试用例描述 |
输入参数 |
期望输出 |
||
a |
b |
c |
|||
1 |
基本路径测试1 |
||||
2 |
基本路径测试2 |
||||
3 |
基本路径测试3 |
||||
4 |
|||||
5 |
|||||
分析:9个区域,8个谓词节点,路径条数为9。
序号
测试用例描述
输入参数
期望输出
a
b
c
1
基本路径测试1
9
8
7
(12,18)
2
基本路径测试2
9
7
8
(6,7)
3
基本路径测试3
10
5
5
(6,7)
4
基本路径测试4
4
3
20
(5,7)
5
基本路径测试5
23
21
20
(12,15)
6
基本路径测试6
10
9
8
(12,18)
7
基本路径测试7
6
8
10
(6,7)
8
基本路径测试8
1
5
9
(6,7)
9
基本路径测试9
1
5
10
(5,7)
package io.shentuzhigang.demo.design;import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test;import java.awt.*;/*** @author ShenTuZhiGang* @version 1.0.0* @date 2020-12-24 19:00*/ public class PathTest {@Testpublic void t(){Assertions.assertEquals(Path.Coverage(9,8,7),new Point(12,18));Assertions.assertEquals(Path.Coverage(9,7,8),new Point(6,7));Assertions.assertEquals(Path.Coverage(10,5,5),new Point(6,7));Assertions.assertEquals(Path.Coverage(4,3,20),new Point(5,7));Assertions.assertEquals(Path.Coverage(23,21,20),new Point(12,15));Assertions.assertEquals(Path.Coverage(10,9,8),new Point(12,18));Assertions.assertEquals(Path.Coverage(6,8,10),new Point(6,7));Assertions.assertEquals(Path.Coverage(1,5,9),new Point(6,7));Assertions.assertEquals(Path.Coverage(1,5,10),new Point(5,7));} }
4. 设计一个静态方法,接收一个字符串,判断该字符串是否为一个格式正确的电话号码。所谓正确格式,有以下规则:
1)如果含3位数值,首位需为1;(110等)
2)如果含8位数值,首位不为0;(本地座机号码)
3)如果含11位数值,首位需为1(手机号码)或0(北京等地座机号码);
4)如果含12位数值,首位需为0;(杭州等地座机号码,第5位不检测)
(国外号码等情况不考虑)
请结合等价类方法给出该方法的测试用例,并基于JUnit,写出测试类。
方法:
1)等价类分为:
有效等价类:是指对于程序的规格说明来说,是合理的,有意义的输入数据构成的集合。
无效等价类:是指对于程序的规格说明来说,是不合理的,无意义的输入数据构成的集合。
2)确立等价类划分原则
原则1:若规定了取值范围,或输入值的个数,则可以确立一个有效等价类和两个无效等价类。
例:程序对输入条件的要求是:…输入数是从1到999…
则 有效等价类是:1≦输入数≦999;
两个无效等价类是:输入数〈1 或 输入数>999
原则2:如果规定了输入数据的一组值,而且程序要对每种输入数据分别处理,则可为每种输入值确立一个有效等价类,此外针对这组值确立一个无效等价类,它是所有不允许的输入值的集合。
例:教师上岗方案中规定对教授、副教授、讲师和助教分别计算分数,做相应的处理。因此可以确定4个有效等价类为教授、副教授、讲师和助教,一个无效等价类,它是所有不符合以上身分的人员的输入值的集合。
原则3:若规定了输入值的集合,或者是规定了“必须如何”的条件,则可确立一个有效等价类和一个无效等价类。
例:某种语言对变量标识符规定必须“以字母打头”,则所有以字母打头的构成有效等价类,而不以字母打头的归于无效等价类。
原则4:如果规定输入数据为整型,则可划分出正整数、零和负整数三个有效类,其他数据为无效类。
原则5:如果程序处理对象是表格,则应使用空表、含一项和多项的表。
3)在确立了等价类之后,建立等价类表,列出所有划分出的等价类。
例如:
4)设计测试用例,覆盖所有的有效等价类组合,和所有的无效等价类组合。
序号 |
测试用例描述 |
输入参数 |
期望输出 |
覆盖范围 |
||
位数 |
首位 |
用例 |
||||
1 |
有效等价类 |
3 |
1 |
110 |
true |
1,5,8 |
2 |
无效等价类 |
3 |
2 |
222 |
false |
2 |
…… |
3 |
5)Junit测试类:
静态方法
package io.shentuzhigang.demo.design;import java.util.regex.Pattern;/*** @author ShenTuZhiGang* @version 1.0.0* @date 2020-12-24 16:24*/ public class PhoneNumber {public static boolean check(String s){Pattern pattern = Pattern.compile("^[\\d]*$");if(pattern.matcher(s).matches()){if(s.length()==3){return s.startsWith("1");}else if(s.length()==8){return s.startsWith("0");}else if(s.length()==11){return s.startsWith("1") || s.startsWith("0");}else if(s.length()==12){return s.startsWith("0");}}return false;} }
等价类表
输入等价类
合理等价类
不合理等价类
电话号码
①首位为1的3位数字字符
②首位为0的8位数字字符
③首位为1或0的11位数字字符
④首位为0的12位数字字符
⑤有非数字字符
⑥位数不合法
⑦首位不合法
测试用例
序号
测试用例描述
输入参数
期望输出
覆盖范围
位数
首位
用例
1
有效等价类
3
1
110
true
1,5,7
2
无效等价类
3
2
222
false
1,7
3
有效等价类
8
0
01111111
true
2
4
无效等价类
8
1
11111111
false
2
5
有效等价类
11
1
11111111111
true
3
6
有效等价类
11
0
01111111111
true
3
7
无效等价类
11
1
1111111a110
false
3,5
8
无效等价类
11
0
01111111-110
false
3,5
9
有效等价类
12
0
011111111111
true
4
10
无效等价类
12
1
111111111111
false
4
11
无效等价类
1
1
1
false
6
12
无效等价类
7
1
1111111
false
6
13
无效等价类
8
1
101011a0
false
2,5
Junit测试类
package io.shentuzhigang.demo.design;import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import org.junit.platform.commons.annotation.Testable;/*** @author ShenTuZhiGang* @version 1.0.0* @date 2020-12-24 17:06*/ @Testable public class PhoneNumberTest{@Testpublic void testCheckPhoneNumber1(){Assertions.assertTrue(PhoneNumber.check("110"), "电话号码合法");}@Testpublic void testCheckPhoneNumber2(){Assertions.assertFalse(PhoneNumber.check("222"), "电话号码不合法");}@Testpublic void testCheckPhoneNumber3(){Assertions.assertTrue(PhoneNumber.check("01111111"), "电话号码合法");}@Testpublic void testCheckPhoneNumber4(){Assertions.assertFalse(PhoneNumber.check("11111111"), "电话号码不合法");}@Testpublic void testCheckPhoneNumber5(){Assertions.assertTrue(PhoneNumber.check("11111111111"), "电话号码合法");}@Testpublic void testCheckPhoneNumber6(){Assertions.assertTrue(PhoneNumber.check("01111111111"), "电话号码合法");}@Testpublic void testCheckPhoneNumber7(){Assertions.assertFalse(PhoneNumber.check("1111111a110"), "电话号码不合法");}@Testpublic void testCheckPhoneNumber8(){Assertions.assertFalse(PhoneNumber.check("01111111-110"), "电话号码不合法");}@Testpublic void testCheckPhoneNumber9(){Assertions.assertTrue(PhoneNumber.check("011111111111"), "电话号码合法");}@Testpublic void testCheckPhoneNumber10(){Assertions.assertTrue(PhoneNumber.check("011111111111"), "电话号码合法");}@Testpublic void testCheckPhoneNumber11(){Assertions.assertFalse(PhoneNumber.check("1"), "电话号码不合法");}@Testpublic void testCheckPhoneNumber12(){Assertions.assertFalse(PhoneNumber.check("1111111"), "电话号码不合法");}@Testpublic void testCheckPhoneNumber13(){Assertions.assertFalse(PhoneNumber.check("101011a0"), "电话号码不合法");} }
测试结果
参考文章
Junit4单元测试的基本用法
Junit3 单元测试 用等价类测试电话号码
《软件工程》实验报告——软件测试相关推荐
- 软件工程导论-实验报告-软件测试
软件工程导论-实验报告-软件测试 [问题描述] 一元二次方程式 ax2+bx+c=0的求根程序有以下功能: 1)输入A.B.C三个系数: 2)根据根的性质的:两个相等或不相等的实根,或无实根,输出相应 ...
- 如何编写一份软件工程实验报告
软件工程实验报告,实际上写的是一份软件需求说明书. 首先是封面.说明自己的个人信息,项目,班级,姓名,指导教师. 然后是正文部分: 正文部分,第一,介绍一下自己要做的项目 第二,可行性研究.用最小的代 ...
- 软件工程实验报告二模板
软件工程实验报告二 软件可行性分析报告编写 目录 附件一.可行性研究报告 1引言 1.1编写目的 1.2背景 1.3定义
- 软件工程实验报告 一
软件工程实验报告 一 一.实验名称 桌面小工具需求分析 二.实验目的 完成几个实用应用系统的需求分析,建立需求模型计: 系统掌握软件开发过程中需求分析报告的写法. 三.实验主要内容 将整个需求分析过程 ...
- 淮海工学院软件测试技术实验三功能测试,软件工程-实验3软件测试技术实验(7页)-原创力文档...
淮海工学院计算机工程学院 实验报告书 课程名: <软件工程> 题 目: 实验3软件测试技术实验 学 号: 2014140093 班 级: Z计121 姓 名: 薛慧君 评语: 评语: 成绩 ...
- 软件测试性能实验报告,软件测试实验报告.doc
软件测试实验报告 实验报告 课程名称 软件测试技术 实验项目名称 性能测试工具LoadRunner的使用 班级与班级代码 实验室名称(或课室) 专 业 软件工程 任课教师 学 号: 姓 名: 实验日期 ...
- 软件测试与维护实验报告,软件测试技术与实践实验报告
软件测试技术与实践实验报告 (11页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 9.90 积分 北华大学计算机科学技术学院实 验 报 告课程名称 软件测 ...
- 天津理工大学计算机项目管理实验四,天津理工大学软件工程实验报告4.docx
天津理工大学 计算机科学与工程学院 实验报告 2017 至 2018学年第一学期 课程名称 软件工程 学号学生姓名 张琳琳 年级 2015 专业 计算 教学班号 3 实验地点 7-215 实验时间 2 ...
- qtp软件测试网站实验报告,软件测试实验报告-QTP的使用
软件测试实验报告-QTP的使用 (7页) 本资源提供全文预览,点击全文预览即可全文预览,如果喜欢文档就下载吧,查找使用更方便哦! 9.9 积分 西南科技大学计算机学院实验报告实验名称 QTP的使丿tl ...
- PHP实验报告 点餐系统,点餐系统软件工程实验报告.doc
学 生 实 验 报 告 (理工类) Introduction to 课程名称:Software Engineering 专业班级: 10计算机科学与技术(单) 学生学号: 学生姓名: 所属院部: 信息 ...
最新文章
- (转自scrum中文网)给Scrum Master的十个建议,你值得拥有
- 机器学习——深度学习(Deep Learning)
- Openwebmail在Ubuntu Linux上的安装过程
- 软体定义网路(SDN)的多重意义
- android RSA加密
- 第二节:如何正确使用WebApi和使用过程中的一些坑
- 【转】Nutz | Nutz项目整合Spring实战
- 在struts2 中通过ActionContext访问Session对象
- anaconda cuda路径_anaconda+cuda+cudann+tensorflow环境安装
- 剑指Offer之复杂链表的复制
- JavaScript:对象都是这样生成的!
- 传递给 left 或 substring 函数的长度参数无效_MySQL:函数入门实例
- Android ——游戏开发之文字冒险游戏
- 中美联合挫败Conficker蠕虫大攻击
- 欢迎使用CSDN-markdown编辑器wewqewqew
- 聚合支付系统设计(三)
- word流程图两条线的端点连接_word 2013流程图连线 word流程图连线
- dts同步常见问题_阿里云DTS数据同步常见问题(一)
- Ubuntu完全教程
- OpenCV - imwrite保存透明PNG
热门文章
- 控制好你的 Wordpress 侧边栏
- c语言口令验证模块加强版,[C语言学习第3章口令验证模块的开发.ppt
- 我的世界java和pe版_《我的世界》pe版不一样的方块世界
- 我是学计算机的上银行考什么条件,计算机专业能报考银行哪些岗位
- 前端vue适配不同的分辨率_浅析 React / Vue 跨端渲染原理与实现
- oss图片上传api_交互式核保系统:api明细:图片上传oss接口
- mysql6支持connect by_mysql 实现oracle start with connect by递归
- c 调用java post方法_C#调用Java方法(详细实例)
- linux 空格函数,linux c语言的split函数和空格处理函数
- java中注解的解析_【Java】中的注解与注解解析器