第4周小组作业:WordCount优化
Github:https://github.com/RicardoDZX/wcPro
一、PSP表格
PSP2.1 |
PSP阶段 |
预估耗时 (分钟) |
实际耗时 (分钟) |
Planning |
计划 |
||
· Estimate |
· 估计这个任务需要多少时间 |
15 | 15 |
Development |
开发 |
||
· Analysis |
· 需求分析 (包括学习新技术) |
50 | 50 |
· Design Spec |
· 生成设计文档 |
20 | 20 |
· Design Review |
· 设计复审 (和同事审核设计文档) |
20 | 20 |
· Coding Standard |
· 代码规范 (为目前的开发制定合适的规范) |
10 | 10 |
· Design |
· 具体设计 |
20 | 20 |
· Coding |
· 具体编码 |
200 | 180 |
· Code Review |
· 代码复审 |
30 | 30 |
· Test |
· 测试(自我测试,修改代码,提交修改) |
30 | 30 |
Reporting |
报告 |
||
· Test Report |
· 测试报告 |
120 | 120 |
· Size Measurement |
· 计算工作量 |
15 | 15 |
· Postmortem & Process Improvement Plan |
· 事后总结, 并提出过程改进计划 |
15 | 15 |
合计 |
545 | 525 |
二、模块编写和测试
这次小组作业,本人所负责的模块是单词分析,即单词提取和单词频率统计,然后把统计结果存储到map中。下面对该模块的设计和测试进行说明。
三、模块设计
1.第一步,先在分析类中定义统计结果保存集和计数器;
public Map<String, Integer> map = new HashMap<>(); public int counter;
2.第二步,定义好分析函数的结构,便于测试
public Map process(String filename) throws Exception{ BufferedReader buffer = new BufferedReader(new InputStreamReader(new FileInputStream(filename))); return map; }
3. 第三步,实现单词分析功能,在分析过程中把分析结果保存进map即可
String line = null; while((line = buffer.readLine()) != null ) { if( line.length() == 0 ) { continue; } String str = line.trim(); StringBuilder builder = new StringBuilder(); for(int i = 0; i < str.length(); i++) { if(Character.isLetter(str.charAt(i))) { builder.append(str.charAt(i)); } else if( str.charAt(i) == '-' && (i < str.length() - 1) && Character.isLetter(str.charAt(i + 1)) ) { builder.append(str.charAt(i)); } else if(builder.length() != 0){ counter++; String string = builder.toString().toLowerCase(); if(map.get(string) == null) { map.put(string, 1); } else { map.replace(string, map.get(string) + 1); } builder.delete(0, builder.length()); } } // 边界, if(builder.length() != 0){ counter++; String string = builder.toString().toLowerCase(); if(map.get(string) == null) { map.put(string, 1); } else { map.replace(string, map.get(string) + 1); } builder.delete(0, builder.length()); } }
四、测试模块设计
因为所实现的功能主要为单词分析和词频统计,所以这里主要测试这两个功能,具体测试用例分为短文本和长文本,短文本为作业所提供的经典样例,长文本为英文文摘。
五、单元测试结果
单元测试实现:
长文本:
@Test() public void test001() throws Exception{ WordAnalysis wordAnalysis = new WordAnalysis(); // 将所要测试的样本的正确分析结果保存进map以与函数分析结果进行比较 int counter = 47; // 比较测试结果的正确性 assertEquals(counter, wordAnalysis.longProcess("winterOfWorld/1.txt")); } @Test() public void test002() throws Exception{ WordAnalysis wordAnalysis = new WordAnalysis(); // 将所要测试的样本的正确分析结果保存进map以与函数分析结果进行比较 int counter = 106; // 比较测试结果的正确性 assertEquals(counter, wordAnalysis.longProcess("winterOfWorld/2.txt")); } @Test() public void test003() throws Exception{ WordAnalysis wordAnalysis = new WordAnalysis(); // 将所要测试的样本的正确分析结果保存进map以与函数分析结果进行比较 int counter = 32; // 比较测试结果的正确性 assertEquals(counter, wordAnalysis.longProcess("winterOfWorld/3.txt")); }
短文本:
@Test() public void test016() throws Exception{ Map<String, Integer> map = new HashMap<>(); WordAnalysis wordAnalysis = new WordAnalysis(); // 将所要测试的样本的正确分析结果保存进map以与函数分析结果进行比较 map.put("let", 1); map.put("s", 1); // 比较测试结果的正确性 assertEquals(map, wordAnalysis.process("winterOfWorld/exam_1.txt")); } @Test() public void test017() throws Exception{ Map<String, Integer> map = new HashMap<>(); WordAnalysis wordAnalysis = new WordAnalysis(); // 将所要测试的样本的正确分析结果保存进map以与函数分析结果进行比较 map.put("content-based", 1); // 比较测试结果的正确性 assertEquals(map, wordAnalysis.process("winterOfWorld/exam_2.txt")); }
具体测试用例可以参考上传到github的用例, 全部测试正常。
扩展任务
一、开发规范说明
这里的开发规范参考了阿里巴巴的JAVA风格指南手册。我所写的代码也基本符合规范所规定的。
二、交叉代码评审
我这次参加了16984同学的代码评审,该同学的代码比较接近上述说明的规范。例如:
public List<Map.Entry<String,Integer>> mySort2(Map<String,Integer> map) { int edge = 100; List<Map.Entry<String, Integer>> res = new ArrayList<Map.Entry<String, Integer>>(); if (map.size() != 0) { List<Map.Entry<String, Integer>> mList = new ArrayList<Map.Entry<String, Integer>>(map.entrySet()); Collections.sort(mList, new Comparator<Map.Entry<String, Integer>>() { @Override public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) { return o2.getValue() - o1.getValue(); } }); //int edge=100; int sizet; if (map.size() <= edge) { sizet = map.size(); } else if(!mList.get(edge-1).getValue().equals(mList.get(edge).getValue())){ sizet = 100; }else{ int maxEdge = edge; while(mList.get(maxEdge).getValue().equals(mList.get(edge).getValue())){ maxEdge++; } sizet = maxEdge; } for (int i = 0; i < sizet; i++) { res.add(mList.get(i)); } }
上述代码中变量的定义,注释的内容和形式都比较完整,体现了对规范的遵守和执行,代码分布规则,运行结果正确,并且稳定性很好。
三、静态代码扫描
因为采用的是Intellij IDEA集成开发环境, 所以在阿里巴巴的JAVA规范手册的github地址那里下载扫描插件然后进行扫描。
单元测试运行结果:
单元测试扫描结果
四、组内代码分析
从大家的代码、测试结果、运行情况来看,我们小组的同学的代码的规范和健壮性很好。例如:
小组贡献评价
小组成员给的分数是0.26。
小结
在这次小组作业中,本人感觉在软件质量测试、代码规范方面有了更加深刻的认识。