一、GitHub地址
https://github.com/Asfalas/wcPro
二、PSP表格
PSP2.1 | PSP阶段 | 预估耗时 (分钟) | 实际耗时 (分钟) |
Planning | 计划 | 60 | 60 |
· Estimate | · 估计这个任务需要多少时间 | 20 | 25 |
Development | 开发 | 180 | 200 |
· Analysis | · 需求分析 (包括学习新技术) | 50 | 30 |
· Design Spec | · 生成设计文档 | 50 | 30 |
· Design Review | · 设计复审 (和同事审核设计文档) | 10 | 20 |
· Coding Standard | · 代码规范 (为目前的开发制定合适的规范) | 30 | 30 |
· Design | · 具体设计 | 50 | 40 |
· Coding | · 具体编码 | 120 | 120 |
· Code Review | · 代码复审 | 30 | 20 |
· Test | · 测试(自我测试,修改代码,提交修改) | 400 | 450 |
Reporting | 报告 | 50 | 20 |
· Test Report | · 测试报告 | 60 | 50 |
· Size Measurement | · 计算工作量 | 10 | 10 |
· Postmortem & Process Improvement Plan | · 事后总结, 并提出过程改进计划 | 30 | 30 |
合计 | 1150 | 1135 |
三、基本任务
1.接口实现 我在这次的小组作业中负责的是输入控制与从文件中读取内容的部分,下面就对这两部分分别进行实现说明:
(1)输入控制
输入控制主要是对输入的文件名进行合法性分析,及对不合乎规范的文件名输入进行筛除。不合理的文件名格式有以下几种:空输入、文件名为多个、文件名不是“.txt”结尾
只需要对这三种情况的文件名进行筛除,并输出相应的提示信息即可,在将正确的文件名输出即可。以下为代码实现:
1 public String judgeInput(String[] args) 2 { 3 String inputFile=""; 4 String appendTxt=".txt";//后缀 5 String windowsTxt="-x";//图形化界面 6 if(args.length==0) 7 { 8 System.out.println("未输入文件名,请重新输入文件名"); 9 inputFile="no file";10 }11 else if(args.length>1)12 {13 System.out.println("多个文件无法同时处理,请输入一个文件名");14 inputFile="so many files";15 }16 else if(!args[0].endsWith(appendTxt))17 {18 if((windowsTxt).equals(args[0])){19 JFileChooser jfc=new JFileChooser(".");20 int returnVal = jfc.showOpenDialog(null);21 if(returnVal == JFileChooser.APPROVE_OPTION)22 {23 //获得打开的文件24 inputFile = jfc.getSelectedFile().getAbsolutePath();25 }26 }27 else28 {29 System.out.println("输入的不是txt格式文件,请重新输入一个txt文件");30 inputFile="not correct file";31 }32 }33 else34 {35 inputFile=args[0];36 }37 this.inputFile = inputFile;38 return inputFile;39 }
(2)文件内容读取
本次的文件读取采用的是对文件中的字符进行逐一处理,使用append将字符一一追加在StringBuffer后,再统一进行输出,以下为代码实现:
1 public void readFileContent() throws IOException 2 { 3 InputStreamReader isr = new InputStreamReader(new FileInputStream(inputFile)); 4 BufferedReader br = new BufferedReader(isr); 5 char s; 6 StringBuilder sb = new StringBuilder(); 7 while((s = (char)br.read()) != (char)-1) 8 { 9 sb.append(s);10 }11 isr.close();12 br.close();13 fileContent = sb.toString().toLowerCase();14 }
2.测试用例设计
写完代码,就是设计代码的测试用例了。对于这两个部分的代码,测试用例只需要对相应的错误与分支分别进行设计用例就好了。首先是输入控制部分。输入控制部分的测试用例主要针对空文件名、多个文件名、文件名后缀不正确分别设计用例即可,如下图:
接下来就是对文件读取内容的部分进行测试用例设计,即对文件中的内容进行修改,在将读取的内容与真实内容相比进行分析,主要注意的是:特殊字符(!@#¥%等)、空格、回车、大量字符以及这些特殊情况的组合进行测试,如下图:
3.单元测试及结果
本次使用的是单元测试框架Junit对代码进行单元测试,由于IDEA编译器中有含有Junit的相关插件,所以配置非常简单,主要对测试脚本进行说明,主要为两个函数的测试脚本编写,这里使用参数进行批量测试,使用expected存储正确的值,用input来表示输出,res存储函数的输出值在进行比较:,由于Object部分的代码过于多,而且都是测试用例的罗列,所以我们只对测试部分的代码进行展示,真正全部的测试代码在GitHub的项目中有:
1 @Test2 public void testJudgeInput() throws Exception { 3 //TODO: Test goes here...4 wcInput wci = new wcInput();5 String res=wci.judgeInput(input1);6 assertEquals(expected1, res);7 8 }
1 public void testGetFileContent() throws Exception { 2 //TODO: Test goes here... 3 if(!expected2.equals("")) 4 { 5 wcInput wci = new wcInput(); 6 wci.judgeInput(input2); 7 wci.readFileContent(); 8 String res1 = wci.getFileContent(); 9 assertEquals(expected2, res1);10 }11 }
下面为测试结果的展示:
4.小组贡献分
经小组讨论,我的小组贡献分为0.26
二、扩展任务:静态测试
1.规范选择
我们在开发过程中选择了《阿里巴巴Java开发手册》,通过老师在博客中发布的链接进行下载:https://yq.aliyun.com/attachment/download/?id=4942
并且可以了解开发手册对应插件在IDEA上的应用:
2.代码分析对象
本次的代码规范检查中,我对学号为:17046 的同学的代码进行了检查,检查结果如下:
(1)该同学的代码中多次在if,else处没有使用大括号
(2)该同学的代码中多次存在魔法值,即没有定义而直接使用的变量
(3)该同学的代码中注释较少,可读性较差
3.静态代码检查
本次静态代码检查使用的是IDEA编译器的Alibaba插件做静态代码扫描,这个插件不需要下载,只需要直接在IDEA编译器中安装即可。
以下为安装插件的教程网站:https://blog.csdn.net/qq_33616529/article/details/78253613
4.静态检查结果
从上面的截图可以看出,代码存在以下几个问题:
(1)代码中while处没有使用大括号
(2)存在魔法值
(3)类名与包名不规范
以下为修改代码的截图:
5.小组存在的问题
我们小组的问题还是挺严重的,这是远超个人问题的问题,我们没有使用UpperCamelCase风格作为类名,导致我在修改自己编写的输出及排序类时,因为重复调用编写的WcOutput类,25个测试方法每一个都要调用一次类名导致手都改断了,包名规范到还好,修改的并不多,不过仍需要注意;再就是在自己的代码下方添加自己的ID,这也是一件看起来十分具有职业精神的一件事,综上,大致就是我们小组共同的问题。
三、高级任务
1.测试数据集设计思路
使用文件大小比较大的数据集来对本程序进行压力测试。我使用了英文的电子书籍《了不起的盖茨比》作为构造测试集,分别构造出了大小为500k,1m,2m,4m,8m,16m的数据集,同时使用了参数化方法对Main函数进行集成的多次测试,观察运行时间。
2.优化前性能指标
程序的大小以及对应的时间消耗
3.同行评审过程
小组成员:张付俊(U201517046)、孙帅(U201517043)、张瑞祺(U201517049)、文宇凡(U201517053)
人员角色分工:张付俊(作者、讲解员)、孙帅(作者,评审员)、张瑞祺(作者,主持人)、文宇凡(作者、评审员)
评审目的:确保要发布质量可靠的代码,发现各种类型的错误,提高代码质量、规范性、一致性和可维护性,提高代码效能。
评审意见:
孙帅:主要对于程序的代码规范角度与部分功能模块角度提出意见
文宇凡:主要对于代码的功能实现角度提出意见
评审结论:
孙帅:(1)代码注释部分较少。可读性较差。
(2)针对输出测试类方法代码存在大量冗余,需要改进。
文宇凡:
(1)将输入字符串传入核心处理模块导致两遍扫描文本,可能会使效率下降,可以一边读文本一边进行排序工作。
(2)代码规范性存在许多问题需要改进。
总体结论:代码需要作者做进一步改进
本次评审的不足:
(1)由于时间较为紧凑,部分细节的评审并未做到面面俱到。
(2)因为代码量较少,评审内容有限,不能发现作者的隐藏问题。
4.测试后得到的结论
通过测试可以发现,本程序可以在较短的时间内完成对500k,1m,2m,4m,8m,16m等大小的文件进行统计词频。
5.优化思路及其指标
优化思路如下:可以对一边对文本进行按字符读取,一边进行单词判断统计等功能,最后使用优化的随机快速排序算法对容器进行排序,因为时间有限,优化尚未完成。
6.总结说明
"通过基本任务、扩展任务、到高级任务的完成,如何体现软件开发、软件测试、软件质量之间的关系"
我认为软件开发、软件测试和软件质量这三者之间是存在紧密的联系的。
软件开发离不开测试。不仅是相互的测试,专业测试员对代码的测试,程序开发者也应对自己的代码进行测试,来保证软件的质量。
首先,程序员是最了解自己的代码逻辑的,因此很方便进行白盒测试,在开发过程中就可以找到自身的不足之处,但是由于程序猿写代码过程中的定式思维,许多隐藏的代码难以被发现,此时就需要测试工程师对代码进行单独测试,只有通过了完整和系统的软件测试的软件的质量才是有一定的保障的。
以上便是本次小组实验所得到的结论。
四、附加功能
使用-x参数可以调出图形界面进行选取文件,代码如下:
1 JFileChooser jfc=new JFileChooser(".");2 int returnVal = jfc.showOpenDialog(null);3 if(returnVal == JFileChooser.APPROVE_OPTION)4 {5 //获得打开的文件6 inputFile = jfc.getSelectedFile().getAbsolutePath();7 }
五、参考文献