软件质量与测试 第四周作业 WordCountPro
基本任务:代码编写+单元测试
Github地址:
https://github.com/Wangmmmm/WordCountPro
PSP2.1:
PSP 2.1 | PSP 阶段 | 预估耗时 (分钟) | 实际耗时 (分钟) |
Planning | 计划 | 20 | 20 |
· Estimate | · 估计这个任务需要多少时间 | 20 | 30 |
Development | 开发 | 80 | 85 |
· Analysis | · 需求分析(包括学习新技术) | 10 | 15 |
· Design Spec | · 生成设计文档 | 10 | 5 |
· Design Review | · 设计复审(和同事审核设计文档) | 10 | 5 |
· Coding Standard | · 代码规范(为目前的开发制定合适的规范) | 10 | 5 |
· Design | · 具体设计 | 10 | 10 |
· Coding | · 具体编码 | 10 | 25 |
· Code Review | · 代码复审 | 10 | 5 |
· Test | · 测试(自我测试,修改代码,提交修改) | 10 | 15 |
Reporting | 报告 | 50 | 45 |
· Test Report | · 测试报告 | 30 | 30 |
· Size Measurement | · 计算工作量 | 10 | 5 |
· Postmortem & Process Improvement Plan | · 事后总结,并提出过程改进设计 | 10 | 10 |
合计 | 150 | 150 |
接口的实现:
我所完成的是输出控制模块,实现的功能是将结果以合理的方式输出,将单词词频排序的结果输出到指定文件中。
我需要完成的任务:
1、调用MyString类中的GetStrings()方法;
2、建立一个新的ArrayList数组out_content,其中的元素为MyString类型;
3、将调用MyString.GetStrings()方法所获得的ArrayList<MyString>数组赋值给out_content数组;
4、将out_content数组中不多于100个内容整合到一个String类型的变量中,便于用BufferedWriter类中的.write()方法将统计结果输出到指定的.txt文件中;
5、用BufferedWriter类中的write()方法输出文件;
关键代码展示:
在Output类中重写构造函数,使得在创建Output这个类的实例的同时就调用MyString.GetStrings()方法,并将MyString.GetStrings()方法返回的ArrayList<MyString>数组赋值给out_content;
1 //构造函数,调用GetStrings方法,获取要输出的内容 2 public Output() { 3 out_content = MyString.GetStrings(); 4 }
遍历out_content,将ArrayList型数组中的内容整理到一个String型变量中,便于之后的输出,在此过程中也要确保输出的排序信息个数不多于100个;
1 //遍历out_content,完成output_String 2 int length = out_content.size(); 3 //确保至多输出前100个排序结果 4 if (length > 100) 5 length = 100; 6 for (int i = 0; i < length; i++) { 7 MyString temp = out_content.get(i); 8 output_String = output_String + "\n\n" + temp.string + " " + temp.GetCount(); 9 }
测试用例设计:
黑盒测试
测试评价原则:
1、测试用例数;
2、测试覆盖度;
3、测试冗余;
4、缺陷定位;
等价划分,目标在于用较少的测试用例数达到对代码的高覆盖度和测试用例的低冗余,故此在本次的黑盒测试用例设计中,我采用了等价划分中的强覆盖方法,旨在对输出模块的所有分类都进行考虑与测试。
模块的等价划分如下图所示:
测试用例如下所述:
要写的文件已经存在,且统计得到的单词数<=100个;
1 @Test 2 //要写的文件已经存在,且统计得到的单词数<=100个 3 void write1() { 4 File read_file = new File("result.txt"); 5 if (!read_file.exists()) { 6 try { 7 read_file.createNewFile(); 8 } catch (Exception e1) { 9 e1.printStackTrace(); 10 } 11 } 12 String expected_string = writeDocument_100(); 13 String content = getContent(); 14 //对String类型对象进行比较 15 assertEquals(expected_string, content); 16 }
要写的文件已经存在,且统计得到的单词数>100个;
1 @Test 2 //要写的文件已经存在,且统计得到的单词数>100个 3 void write2() { 4 File read_file = new File("result.txt"); 5 if (!read_file.exists()) { 6 try { 7 read_file.createNewFile(); 8 } catch (Exception e1) { 9 e1.printStackTrace(); 10 } 11 } 12 String expected_string = writeDocument_100_more(); 13 String content = getContent(); 14 //对String类型对象进行比较 15 assertEquals(expected_string, content); 16 }
要写的文件不存在,且统计得到的单词数<=100个;
1 @Test 2 //要写的文件不存在,且统计得到的单词数<=100个 3 void write3() { 4 File read_file = new File("result.txt"); 5 if (read_file.exists()) { 6 read_file.delete(); 7 } 8 String expected_string = writeDocument_100(); 9 String content = getContent(); 10 //对String类型对象进行比较 11 assertEquals(expected_string, content); 12 }
要写的文件不存在,且统计得到的单词数>100个;
1 @Test 2 //要写的文件不存在,且统计得到的单词数>100个 3 void write4() { 4 File read_file = new File("result.txt"); 5 if (read_file.exists()) { 6 read_file.delete(); 7 } 8 String expected_string = writeDocument_100_more(); 9 String content = getContent(); 10 //对String类型对象进行比较 11 assertEquals(expected_string, content); 12 }
统计单词的out_content数组为null;
1 @Test 2 //统计单词的out_content数组为null 3 void write5() { 4 String expected_string = writeDocument_null(); 5 String content = getContent(); 6 //对String类型对象进行比较 7 assertEquals(expected_string, content); 8 }
以上所述的测试用例在模块的等价划分如下图所示:
白盒测试
覆盖指标:
1、语句覆盖;
2、判定覆盖;
3、条件覆盖;
4、条件组合覆盖;
5、判定条件覆盖;
6、修正的判定条件覆盖;
本输出模块的结构图如下所示:
依据模块的结构,我采用语句覆盖,判定覆盖和条件覆盖的方法对本模块进行测试,分为以下四种测试用例;
白盒测试的测试用例:
要写入的文件已经存在,且统计得到的单词数<=100个;
1 //要写入的文件已经存在,且统计得到的单词数<=100个; 2 static void whiteBox1() { 3 File read_file = new File("result.txt"); 4 if (!read_file.exists()) { 5 try { 6 read_file.createNewFile(); 7 } catch (Exception e1) { 8 e1.printStackTrace(); 9 } 10 } 11 String expected_string = writeDocument_100(); 12 String content = getContent(); 13 //对String类型对象进行比较 14 if (expected_string.equals(content)) 15 System.out.println("whiteBox1 test passed!"); 16 }
要写入的文件已经存在,且统计得到的单词数>100个;
1 //要写的文件已经存在,且统计得到的单词数>100个 2 static void whiteBox2() { 3 File read_file = new File("result.txt"); 4 if (!read_file.exists()) { 5 try { 6 read_file.createNewFile(); 7 } catch (Exception e1) { 8 e1.printStackTrace(); 9 } 10 } 11 String expected_string = writeDocument_100_more(); 12 String content = getContent(); 13 //对String类型对象进行比较 14 if (expected_string.equals(content)) 15 System.out.println("whiteBox2 test passed!"); 16 }
要写入的文件不存在,且统计得到的单词数<=100个;
1 //要写的文件不存在,且统计得到的单词数<=100个 2 static void whiteBox3() { 3 File read_file = new File("result.txt"); 4 if (read_file.exists()) { 5 read_file.delete(); 6 } 7 String expected_string = writeDocument_100(); 8 String content = getContent(); 9 //对String类型对象进行比较 10 if (expected_string.equals(content)) 11 System.out.println("whiteBox3 test passed!"); 12 }
要写入的文件不存在,且统计得到的单词数>100个;
1 //要写的文件不存在,且统计得到的单词数>100个 2 static void whiteBox4() { 3 File read_file = new File("result.txt"); 4 if (read_file.exists()) { 5 read_file.delete(); 6 } 7 String expected_string = writeDocument_100_more(); 8 String content = getContent(); 9 //对String类型对象进行比较 10 if (expected_string.equals(content)) 11 System.out.println("whiteBox4 test passed!"); 12 }
测试评价与模块评价:
黑盒测试用例运行截图:
本项目GitHub中test文件夹下的OutputTest.java文件即为黑盒测试的.java文件
白盒测试用例运行截图:
本模块的白盒测试程序我写在了程序的主动类中,通过在main()函数中调用相应的函数名即可运行测试
测试用例设计清单:
测试质量评价:
总体来说,本测试的质量很高,在黑盒测试中做到了用较少的测试用例数达到对代码的高覆盖度和测试用例的低冗余,在白盒测试中做到了语句覆盖,判定覆盖和条件覆盖,所以综上对次模块的测试十分完备。
被测模块评价:
本输出模块在黑盒测试的强覆盖测试和白盒测试的语句覆盖,判定覆盖和条件覆盖的测试中,表现良好,所有测试全部通过,综上可知本输出模块的质量较高。
小组贡献分:
经过小组讨论,最终认定我负责的输出模块所获的小组贡献分为:0.25
扩展任务:静态测试
开发规范文档:
在本项目的静态测试中,我们选取了《阿里巴巴Java开发手册》作为评审规范
代码评价:
本次测试中我采用上述规范分析了学号后五位为17047的同学所编写的代码
问题分析:
1、无充分注释说明:代码中无注释,导致评审员及讲解员对代码的理解难度增大,评审过程的效率大打折扣;
2、属性名命名不规范:一些变量的命名的含义显示不明确,另外在数据类型变量的命名中没有加入下划线来命名;
3、方法名命名不规范:类中的方法名应小写首字母,以此来遵循代码规范,但该同学却大些了首字母;
4、无单元测试:没有对单个独立的功能进行单元测试,仅完成了整个功能的实现,对整个项目进行测试;
5、无异常处理:没有对可能使程序发生崩溃的异常进行异常处理;
静态代码检查工具:
我们组使用的静态代码分析工具是名为"FindBugs-IDEA"的插件,可以在IDEA中直接下载安装,如下所示:
工具扫描结果展示与分析:
扫描结果展示:
结果分析:
1、存在多次实例化一个对象,使得前几次的实例化变成无用功,消耗资源;
2、存在声明并分配了空间的对象在之后却从未被调用的现象,浪费资源;
3、在使用完java.io.Reader中的方法后,没有释放资源;
4、使用的方法依赖于系统编码,虽然方便,但一经使用就变成了一个技术债务,应为系统编码是不可知的;
5、存在着应该被声明为final型却没有的变量;
经过对比观察可知,成员之间查看讲解代码虽然也能发现很多代码的规范问题,但是测试工具的分析结果却更加的细致、到位,它能将一些仅凭观察无法发现的错误都一一找出。
小组代码分析:
本次项目中,小组合作所编写的代码中主要存在的问题是注释欠缺,在很多本应用简洁的语言来说明的关键点上,却缺少了注释,这就使得组员间编写的功能相互对接时存在不理解、误解等的问题,这使得一些不该出现的错误频频发生,致使程序开发的效率大大降低。
我们的改进方法就是添加注释并多多沟通交流,这使得组员间可以更好更快地理解对方代码编写的意图,从而使得前面所述的问题都迎刃而解,大大提高了程序开发的效率。
参考文献链接:
JUnit 5 User Guide
https://junit.org/junit5/docs/current/user-guide/
Git教程 - 廖雪峰的官方网站
https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000