哈尔滨工业大学
计算学部/软件学院
2022年秋季学期
2020级本科《软件过程与工具》课程(3.0学分)
作业报告
作业3:软件测试报告
姓名 | 学号 | 联系方式 |
石卓凡 | 120L021011 | 944613709@qq.com/18974330318 |
目 录
1 作业目的与要求........................................................................................................ 1
2 软件测试环境搭建.................................................................................................... 1
2.1 自定测试项目环境搭建.................................................................................. 1
2.2 指定软件系统测试环境搭建.......................................................................... 1
2.2.1 环境配置描述............................................................................................... 2
2.2.2 搭建过程描述............................................................................................... 2
3 软件测试过程及结果................................................................................................ 2
3.1 白盒测试(单元测试).................................................................................. 2
3.1.1 顺序结构程序测试....................................................................................... 2
3.1.2 分支结构程序测试....................................................................................... 5
3.1.3 循环结构程序测试....................................................................................... 9
3.2 集成/系统测试............................................................................................... 15
3.2.1 学校本科生统一身份认证系统部分功能模块测试................................. 15
3.2.2 学校本科生门户平台系统UI可用性测试与评价.................................. 21
- 作业目的与要求
(1)学习软件测试的基本方法;
(2)实践软件测试的基本过程;
(3)掌握单元测试、集成测试的方法;
(4)掌握白盒测试和黑盒测试的基本方法;
(5)学习UI的基本测评和用户体验;
(6)本次作业要求主要由个人独立完成。
- 软件测试环境搭建
- 自定测试项目环境搭建
X64 CPU;2GHz;2G RAM;256GHD Disk 以上
- 软件环境
Windows7/10 64位以上;VirtualBox/Vmware 11以上;Ubuntu 16.04 LTS 64位/优麒麟 64位 以上;
- 开发工具
IDEA
下载IDEA
- IDE为idea,安装idea和配置jdk11。,idea采用professional版本2021.2.3,关于试用30天的限制,我在假期之前遇见的这个问题花了一段时间摸索,最终采用的是补丁破解试用
- 在IDEA中下载JDK11,并且配置JDK11
- 选取程序
软件构造Lab3---投票系统部分代码
-
- 指定软件系统测试环境搭建
- 硬件环境
X64 CPU;2GHz;2G RAM;256GHD Disk 以上
- 软件环境
Windows7/10 64位以上;VirtualBox/Vmware 11以上;Ubuntu 16.04 LTS 64位/优麒麟 64位 以上;
- 浏览器
Google浏览器
- 网络代理
EasyConnect校内网vpn
- 选取系统
哈工大统一身份认证,今日哈工大
http://ids-hit-edu-cn-s.ivpn.hit.edu.cn/
-
-
- 环境配置描述
-
- Windows10系统
- 校外网络,使用EasyConnect作为VPN转换为校园网络
- Google浏览器
-
- 搭建过程描述
-
- 下载安装EasyConnect
- 输入i.hit.edu.cn
- 登录学工号和密码
- 成功接入校园网VPN
- 软件测试过程及结果
- 白盒测试(单元测试)
- 顺序结构程序测试
- 白盒测试(单元测试)
3.1.1.1测试对象
源代码
- //immutable
- public class VoteType {
- // key为选项名、value为选项名对应的分数
- private Map<String, Integer> options = new HashMap<>();
- // Rep Invariants
- // 选项名key不能为"",其中不允许出现空格
- // options.size()选项个数需要>=2
- // Abstract Function
- // AF(String,Integer)->选项其中key为选项名、value为选项名对应的分数
- // Safety from Rep Exposure
- // 所有的数据域都是私有的
- // 用Collections.unmodifiableMap()转化为不可变类型返回给外部
- /**
- *
- * @param options voteType对应的选项名和分数
- */
- public VoteType(Map<String,Integer> options) {
- this.options=new HashMap<>(options);
- checkRep();
- }
流程图
根据传入的Map,创建一个投票类型对象
图3.1.1.1流程图
3.1.1.2测试用例设计
分类 | 细则 | 样例 | |
不存在投票选项 | 空白 | Null | |
存在投票选项 | Key符合条件 | options2.put("喜欢",2); options2.put("不喜欢",0); options2.put("无所谓",1); | |
Key不符合条件 | options3.put("特别特别的喜欢",2); options3.put(" ",0); options3.put("无 所 谓",1); |
3.1.1.3测试过程与结果
测试步骤:
- Stub程序创建options
- Stub程序给定options的变量
- 利用junit进行判定
针对VoteType(Map<String,Integer> options)
1.不存在投票选项
2.存在投票选项
2.1Key符合条件
2.2Key不符合条件
结果:
3.1.1.4 Driver或Stub程序的编制
- /**
- * 针对VoteType(Map<String,Integer> options)
- * 1.不存在投票选项
- * 2.存在投票选项
- * 2.1Key符合条件
- * 2.2Key不符合条件
- */
- @Test
- public void VoteTypeTest_NotRegex()
- {
- Map<String, Integer> options = new HashMap<>();
- VoteType voteType = new VoteType(options);
- assertEquals(options,voteType.getOptions());
- Map<String, Integer> options2 = new HashMap<>();
- options2.put("喜欢",2);
- options2.put("不喜欢",0);
- options2.put("无所谓",1);
- VoteType voteType2 = new VoteType(options2);
- assertEquals(options2,voteType2.getOptions());
- // Map<String, Integer> options3 = new HashMap<>();
- // options3.put("特别特别的喜欢",2);
- // options3.put(" ",0);
- // options3.put("无 所 谓",1);
- // VoteType voteType3 = new VoteType(options3);
- // assertFalse(false,voteType3.getOptions());
- }
-
-
- 分支结构程序测试
-
3.1.2.1测试对象
源代码
- public VoteType(String regex) throws IllegalArgumentException{
- // split的参数是一个正则表达式,‘|’需要转义
- String[] inputOptions = regex.split("\\|");
- //得到 “喜欢”(2)
- //或者得到 “支持”
- if(inputOptions.length < 2) {
- throw new IllegalArgumentException("非法输入:选项少于两个");
- }
- Pattern regexWithNum = Pattern.compile("\"(\\S+)\"\\(([-]?\\d+)\\)");
- Pattern regexWithoutNum = Pattern.compile("\"(\\S+)\"");
- int unMatchFlag=0;//不匹配次数
- //先尝试匹配有数字模式
- for (String option : inputOptions) {
- Matcher m = regexWithNum.matcher(option);
- if(!m.matches())
- {
- unMatchFlag++;//若这个当前不匹配,不匹配次数+1
- break;
- }
- if (m.group(1).length() > 5)
- throw new IllegalArgumentException("选项名长度超过5");
- options.put(m.group(1), Integer.valueOf(m.group(2)));
- }
- if(unMatchFlag==0)
- {
- checkRep();
- return;
- }
- //匹配无数字的等权重格式
- for (String option : inputOptions) {
- Matcher m = regexWithoutNum.matcher(option);
- if(!m.matches())
- {
- unMatchFlag++;//若这个当前不匹配,不匹配次数+1
- break;
- }
- if (m.group(1).length() > 5)
- throw new IllegalArgumentException("选项名长度超过5");
- options.put(m.group(1), 1);
- }
- if(unMatchFlag==2)//代表都不匹配
- throw new IllegalArgumentException("两种情况都不匹配");
- checkRep();
- }
流程图
根据满足特定语法规则的字符串,创建一个投票类型对象
@param regex 遵循特定语法的、包含投票类型信息的字符串(待任务12再考虑)
该字符串的语法规则如下:
// “喜欢”(2)|“不喜欢”(0)|“无所谓”(1)
// 其中,用双引号括起来的文字部分是一个投票选项,长度不超过 5,其中不
// 允许出现空格;用括号括起来的数字是投票选项对应的分数,可以是正整数、0
// 或负整数,不能带小数,正整数不需要使用“+”,但负整数需要使用“-”;不同
// 的投票选项之间用“|”隔开。
// 也可以用如下形式:
// “支持”|“反对”|“弃权”
// 与上面的例子相比,区别是没有分数。这种情况表明各个投票选项的权重是一样的
图3.1.1.1流程图
3.1.2.2测试用例设计
分类 | 细则 | 样例 |
匹配有数字模式 | 不含负数 | "喜欢"(2)|"不喜欢"(0)|"无所谓"(1) |
含负数 | "喜欢"(-2)|"不喜欢"(0)|"无所谓"(1) | |
匹配无数字模式 | 不超过5个长度 | "支持"|"反对"|"弃权" |
超过5个长度 | "支持"|"反对"|"弃权"|"超级支持"|"超级弃权"|"超级超级支持" | |
无法匹配正常模式 | "支持(1)"|"反对"|"弃权" |
3.1.2.3测试过程与结果
测试步骤:
- Stub程序创建options
- Stub程序给定options的变量
- 利用junit进行判定
测试成功:
1.测试带数字的
1.1不含负数
1.2含负数
2.测试不带数字的
测试抛出异常:
1,超过5个长度
2.格式不对
结果:
3.1.2.4 Driver或Stub程序的编制
- /**
- * 针对VoteType(String regex)
- * 测试成功:
- * 1.测试带数字的
- * 1.1不含负数
- * 1.2含负数
- * 2.测试不带数字的
- * 测试抛出异常:
- * 1,超过5个长度
- * 2.格式不对
- */
- @Test
- public void VoteTypeTest_regex()
- {
- //"喜欢"(2)|"不喜欢"(0)|"无所谓"(1)
- Map<String, Integer> options = new HashMap<>();
- options.put("喜欢",2);
- options.put("不喜欢",0);
- options.put("无所谓",1);
- VoteType voteType = new VoteType("\"喜欢\"(2)|\"不喜欢\"(0)|\"无所谓\"(1)");
- assertEquals(options,voteType.getOptions());
- //"喜欢"(-2)|"不喜欢"(0)|"无所谓"(1)
- Map<String, Integer> options3 = new HashMap<>();
- options3.put("喜欢",-2);
- options3.put("不喜欢",0);
- options3.put("无所谓",1);
- VoteType voteType3 = new VoteType("\"喜欢\"(-2)|\"不喜欢\"(0)|\"无所谓\"(1)");
- assertEquals(options3,voteType3.getOptions());
- //"支持"|"反对"|"弃权"
- //没有分数都默认为1
- Map<String, Integer> options2 = new HashMap<>();
- options2.put("支持",1);
- options2.put("反对",1);
- options2.put("弃权",1);
- VoteType voteType2 = new VoteType("\"支持\"|\"反对\"|\"弃权\"");
- assertEquals(options2,voteType2.getOptions());
- assertThrows(IllegalArgumentException.class,()->new VoteType("\"超级超级支持\"|\"反对\"|\"弃权\""),"选项名长度超过5");
- assertThrows(IllegalArgumentException.class,()->new VoteType("\"支持\"(1)|\"反对\"|\"弃权\""),"两种情况都不匹配");
- }
-
-
- 循环结构程序测试
-
3.1.3.1测试对象
源代码
- /**
- * 在addVote中负责检查该选票合法性并标记
- * @param vote 投票
- * @param voter 投票人
- */
- public void checkVote(Vote<C> vote,Voter voter)
- {
- Set<VoteItem<C>> voteItems = vote.getVoteItems();
- for (VoteItem<C> voteItem : voteItems) {
- if(!candidates.contains(voteItem.getCandidate()))
- {
- voteIsLegal.put(vote,false);//包含了不在本次投票活动的候选人
- return;
- }
- if(!voteType.checkLegality(voteItem.getVoteValue()))
- {
- voteIsLegal.put(vote,false);//一张选票中出现了本次投票不允许的选项值
- return;
- }
- for(VoteItem<C> voteItem2 : voteItems)
- {
- if(voteItem2!=voteItem && voteItem2.getCandidate().equals(voteItem.getCandidate()))
- {
- voteIsLegal.put(vote,false);//一张选票中有对同一个候选对象的多次投票
- return;
- }
- }
- }
- for (C candidate : candidates) {
- if(!vote.candidateIncluded(candidate))
- {
- voteIsLegal.put(vote,false);//一张选票中没有包含本次投票活动中的所有候选人
- return;
- }
- }
- //若都无异常
- voteIsLegal.put(vote,true);//鉴定为合法
- }
流程图:
图3.1.3.2.1流程图
3.1.3.2测试用例设计
checkVote测试
四种共用不合法选票的测试
选票不合法情况:
一张选票中没有包含本次投票活动中的所有候选人
一张选票中包含了不在本次投票活动中的候选人
一张选票中出现了本次投票不允许的选项值
一张选票中有对同一个候选对象的多次投票
候选人candidate1.candidate2,candidate3,candidate4
投票人vr1,选票为空
投票人vr2,选票里candidate5,candidate1,candidate2,candidate3
投票人vr3,选票里有candidate1.candidate2,candidate3,candidate4但是出现了本次投票不允许的选项值”like"
投票人vr3,选票里有candidate1.candidate2,candidate5,candidate4
投票人vr4,选票里有candidate1.candidate2,candidate3,candidate5
分类 | 细则 | 样例 |
0次循环 | 从循环入口直接跳到循环出口 | 投票人vr1,选票为空 |
1次循环 | 查找循环初始值方面的错误 | 投票人vr2,选票里candidate5,candidate1,candidate2,candidate3 |
2次循环 | 检查在多次循环时才能暴露的错误 | 投票人vr3,选票里有candidate1.candidate2,candidate3,candidate4但是出现了本次投票不允许的选项值”like" |
m次循环 | 此时的m<n,也是检查在多次循环时才能暴露的错误 | 投票人vr3,选票里有candidate1.candidate2,candidate5,candidate4 |
最大次数循环 | 投票人vr4,选票里有candidate1.candidate2,candidate3,candidate5 |
3.1.3.3测试过程与结果
测试步骤:
候选人candidate1.candidate2,candidate3,candidate4
投票人vr1,选票为空
投票人vr2,选票里candidate5,candidate1,candidate2,candidate3
投票人vr3,选票里有candidate1.candidate2,candidate3,candidate4但是出现了本次投票不允许的选项值”like"
投票人vr3,选票里有candidate1.candidate2,candidate5,candidate4
投票人vr4,选票里有candidate1.candidate2,candidate3,candidate5
- 创建投票人
- 设定投票人权重
- 设定投票类型
- 创建候选人
- 创建投票项
- 创建投票
- 创建投票活动
- 更新投票人投票
结果:
3.1.3.4 Driver或Stub程序的编制
- /**
- * 是statisticTest的检测第二种异常情况:
- * (也是checkVote的测试)
- * 四种共用不合法选票的测试
- * * 选票不合法情况
- * * ? 一张选票中没有包含本次投票活动中的所有候选人
- * * ? 一张选票中包含了不在本次投票活动中的候选人
- * * ? 一张选票中出现了本次投票不允许的选项值
- * * ? 一张选票中有对同一个候选对象的多次投票
- * 具体测试样例:
- *候选人candidate1.candidate2,candidate3,candidate4
- *投票人vr1,选票为空
- *投票人vr2,选票里candidate5,candidate1,candidate2,candidate3
- *投票人vr3,选票里有candidate1.candidate2,candidate3,candidate4但是出现了本次投票不允许的选项值”like"
- *投票人vr3,选票里有candidate1.candidate2,candidate5,candidate4
- *投票人vr4,选票里有candidate1.candidate2,candidate3,candidate5
- */
- @Test
- void checkVote_statistics_BuHeFaTest() {
- // 创建2个投票人
- Voter vr1 = new Voter("v1");
- Voter vr2 = new Voter("v2");
- Voter vr3 = new Voter("v3");
- Voter vr4 = new Voter("v4");
- // 设定2个投票人的权重
- Map<Voter, Double> weightedVoters = new HashMap<>();
- weightedVoters.put(vr1, 1.0);
- weightedVoters.put(vr2, 1.0);
- weightedVoters.put(vr3, 1.0);
- weightedVoters.put(vr4, 1.0);
- // 设定投票类型
- Map<String, Integer> types = new HashMap<>();
- types.put("Support", 1);
- types.put("Oppose", -1);
- types.put("Waive", 0);
- VoteType voteType = new VoteType(types);
- // 创建候选对象:候选人
- Person p1 = new Person("candidate1", 19);
- Person p2 = new Person("candidate2", 20);
- Person p3 = new Person("candidate3", 20);
- ArrayList<Person> candidates = new ArrayList<>();
- candidates.add(p1);
- candidates.add(p2);
- // 创建投票项,前三个是投票人vr1对三个候选对象的投票项,后三个是vr2的投票项
- VoteItem<Person> vi11 = new VoteItem<>(p1, "Support");
- Set<VoteItem<Person>> voteItems1 = new HashSet<>();
- voteItems1.add(vi11);
- VoteItem<Person> vi21 = new VoteItem<>(p1, "Oppose");
- VoteItem<Person> vi22 = new VoteItem<>(p3, "Waive");
- Set<VoteItem<Person>> voteItems2 = new HashSet<>();
- voteItems2.add(vi21);
- voteItems2.add(vi22);
- VoteItem<Person> vi31 = new VoteItem<>(p1, "Oppose");
- VoteItem<Person> vi32 = new VoteItem<>(p2, "like");
- Set<VoteItem<Person>> voteItems3 = new HashSet<>();
- voteItems3.add(vi31);
- voteItems3.add(vi32);
- VoteItem<Person> vi41 = new VoteItem<>(p1, "Support");
- VoteItem<Person> vi42 = new VoteItem<>(p1, "Oppose");
- Set<VoteItem<Person>> voteItems4 = new HashSet<>();
- voteItems4.add(vi41);
- voteItems4.add(vi42);
- // 创建2个投票人vr1、vr2的选票
- Vote<Person> rv1 = new Vote<Person>(voteItems1, new GregorianCalendar(2019, 6, 14, 16, 15, 30));
- Vote<Person> rv2 = new Vote<Person>(voteItems2, new GregorianCalendar(2019, 6, 14, 16, 15, 30));
- Vote<Person> rv3 = new Vote<Person>(voteItems3, new GregorianCalendar(2019, 6, 14, 16, 15, 30));
- Vote<Person> rv4 = new Vote<Person>(voteItems4, new GregorianCalendar(2019, 6, 14, 16, 15, 30));
- // System.out.println("rv1 = " + rv1);
- // System.out.println("rv2 = " + rv2);
- // 创建投票活动
- GeneralPollImpl<Person> poll= new GeneralPollImpl<Person>();
- // 设定投票基本信息:名称、日期、投票类型、选出的数量
- String name = "代表选举";
- GregorianCalendar date = new GregorianCalendar(2019, 6, 14, 16, 15, 30);
- int quantity = 1;
- poll.setInfo(name, date, voteType, quantity);
- // 增加投票人及其权重
- poll.addVoters(weightedVoters);
- poll.addCandidates(candidates);
- // 增加三个投票人的选票
- poll.addVote(rv1, vr1);
- poll.addVote(rv2, vr2);
- poll.addVote(rv3, vr3);
- poll.addVote(rv4, vr4);
- GeneralPollImpl election = poll;
- Map<Vote<Person>, Boolean> voteIsLegal = election.getVoteIsLegal();
- for (Map.Entry<Vote<Person>, Boolean> voteBooleanEntry : voteIsLegal.entrySet()) {
- Boolean isLegal = voteBooleanEntry.getValue();
- assertEquals(false, isLegal);
- }
- }
-
- 集成/系统测试
http://i-hit-edu-cn.ivpn.hit.edu.cn:1080/index#/app/home/index
-
-
- 学校本科生统一身份认证系统部分功能模块测试
-
3.2.1.1测试用例设计
本科生统一身份认证系统
测试样例 | 预期结果 | 最终结果 |
测试空白用户名和密码输入 | 提示空白输入 | √ |
测试空白密码输入 | 提示空白密码输入 | √ |
测试正确用户名和密码输入登录 | 成功登录,跳转主页 | √ |
测试哈工大APP扫码登录 | 成功登录,跳转主页 | √ |
测试QQ登录 | 成功登录,跳转主页 | ×无法使用qq登录 |
测试微信登录 | 成功登录,跳转主页 | √ |
测试一周内免密登录 | 一周内都能免密成功登录,跳转主页 | ×无法一周内免密 |
测试忘记密码找回密码 | 成功找回密码 | √ |
测试账号激活功能 | 跳转到账号激活页面,能完成功能 | √ |
测试登录页面帮助文档 | 文档能够说明登录时候的大部分问题 | √ |
3.2.1.2测试过程与结果
- 测试空白用户名和密码输入
结果:提示请输入用户名
符合预期√
- 测试空白密码输入
结果:提示请输入密码
符合预期√
- 测试正确用户名和密码输入登录
结果:成功登录并跳转主页
符合预期√
- 测试哈工大APP扫码登录
结果:弹出扫码框并且最后可以成功登录
符合预期√
- 测试QQ登录
结果:失败,调用QQ登录或许存在一些bug没以后解决
不符合预期×
- 测试微信登录
结果:弹出扫码框并且最后可以成功登录
符合预期√
- 测试一周内免密登录
结果:一周内没有一直免密登录,未到一周就会提示需要重新登录
不符合预期×
- 测试忘记密码找回密码
结果:成功跳转到忘记密码页面,能够实验修改密码
符合预期√
- 测试账号激活功能
结果:成功跳转到账号激活页面,能够激活账户
符合预期√
- 测试登录页面帮助文档
结果:成功跳转到帮助文档
符合预期√
-
-
- 学校本科生门户平台系统UI可用性测试与评价
-
3.2.2.1测试用例设计
测试样例 | 预期结果 | 最终结果 |
缺省值,登录成功跳转到缺省值 | 默认展示主页 | √ |
输入验证,验证输入的学工号是否符合规范 | 提示学工号不符合规范 | ×无法提示学工号规范格式 |
系统响应,点击某个功能之后之后快速响应 | 快速跳转到新页面 | ×相对于其他网站,速度较慢 |
信息反馈,对于已经删除的校内新闻是否会给出提示 | 提示该内容已被删除 | √ |
3.2.2.2测试过程与结果
- 缺省值,登录成功跳转到缺省值
结果:登陆成功会跳转到首页
符合预期√
- 输入验证,验证输入的学工号是否符合规范
结果:没有提示用户名固定格式出错,而是简单提示用户名或密码有错
不符合预期×
- 系统响应,点击某个功能之后之后快速响应
结果:快速点击多个校内新闻,跳转打开速度较慢
不符合预期×
- 信息反馈,对于已经删除的校内新闻是否会给出提示
结果:校内过时新闻会提示访问页面不存在
符合预期√
3.2.2.3 UI可用性即用户体验评价结果
当前效果 | 可以改进为 |
在主页面的动态效果太少,多数是静态效果 | 可以多一点动态新闻图片展示 |
每一条新闻没有评论功能 | 添加评论功能 |
没有快速点开个人常用应用 | 添加某个用户自己最常用的应用列表 |
没有网站指引说明 | 添加网站指引说明 |
主页一大篇幅我的待办功能略显鸡肋 | 可以调整我的待办的位置 |