第四周小组作业
所有完成的部分都push到组长所建立的GitHub仓库里面
地址为:https://github.com/YinshenYuan/wcPro
基本任务
PSP表格
备注:
最开始没有进行时间预估,按照自己的时间安排进行相应的作业,因此该PSP表格中预估时间与实际完成时间相同。
接口对接
最开始的时候组长已经将对应模块的函数,包括参数,功能和返回值都定了下来,因此自己只需要实现对应的函数即可。个人完成的是将排序好的map输出到指定text文件中,参数是传来的map,返回值为布尔类型,因此是在该函数中完成所有的功能,返回值仅用来进行提醒
主要方法是将map转化为字符串,再创建文件进行输出,
转换代码:需求中提到要删去文件末尾的换行符,因此循环中多了一个判断
Iterator<Map.Entry<String, Integer>> it = map.entrySet().iterator();
while (it.hasNext() && i < N)
{
Map.Entry<String, Integer> entry = it.next();
if(i == 0)
a = entry.getKey() + " " + entry.getValue();
else
a += "\r\n" + entry.getKey() + " " + entry.getValue();
i++;
}
输出代码:包裹try catch来捕捉异常,写文件方法是标准的输出流方法
try
{
File outPut = new File("result.txt");
FileOutputStream outFile = new FileOutputStream(outPut);
outFile.write(a.getBytes());
outFile.flush();
outFile.close();
}
catch (IOException e)
{
System.err.println("Failure to create a text!");
return false;
}
测试用例设计
所写的测试用例主要是对是否正确写入进行判断,
- 不考虑map中是否有信息,因为需求中没有指明空文件为非测试文件,因此不对输入的map进行判断
- 没有对代码中唯一的异常处理进行测试,因为文件写错误包含的几个可能,权限,磁盘问题,无法找到有效的环境进行测试
考虑上面因素,加上需求中说仅保存前100的统计数据,主要在这方面进行测试,边界值0,100,其他值50,200,覆盖了信息多寡基本可能的几个区域
定义三个函数用来提取需要的信息
public static String readFileByChars(String fileName)
{
File file = new File(fileName);
Reader reader = null;
String s = "";
try
{
reader = new InputStreamReader(new FileInputStream(file));
int tempchar;
while ((tempchar = reader.read()) != -1)
s += (char) tempchar;
reader.close();
} catch (Exception e)
{
e.printStackTrace();
}
return s;
}
public static String transformMapintoChar(Map<String, Integer> map)
{
int i = 0;
String s = "";
Iterator<Map.Entry<String, Integer>> it = map.entrySet().iterator();
while (it.hasNext() && i < 100)
{
Map.Entry<String, Integer> entry = it.next();
if(i == 0)
s = entry.getKey() + " " + entry.getValue();
else
s += "\r\n" + entry.getKey() + " " + entry.getValue();
i++;
}
return s;
}
public static int lineCount(String fileName)
{
int l = 0;
String t = null;
File file = new File(fileName);
BufferedReader reader = null;
try
{
reader = new BufferedReader(new FileReader(file));
while ((t = reader.readLine()) != null)
l++;
reader.close();
}
catch (IOException e)
{
e.printStackTrace();
}
return l;
}
先测试数据是否相同,再测试是否输出了正确条的数据,比如即使map中200个数据,最后文件中只存在100个数据,即100行
把预期与实际进行比对,测试全部通过,表明代码基本正确。
@Test
public void test1()
{
Map<String, Integer> map = new HashMap<String, Integer>();
WordCountPro.writeOutput(map);
assertEquals("", readFileByChars("result.txt"));
}
@Test
public void test2()
{
Map<String, Integer> map = new LinkedHashMap<String, Integer>();
for (int i = 0; i < 50; i++)
map.put("the " + i, i);
WordCountPro.writeOutput(map);
assertEquals(transformMapintoChar(map), readFileByChars("result.txt"));
}
@Test
public void test3()
{
Map<String, Integer> map = new LinkedHashMap<String, Integer>();
for (int i = 0; i < 100; i++)
map.put("the " + i, i);
WordCountPro.writeOutput(map);
assertEquals(transformMapintoChar(map), readFileByChars("result.txt"));
}
@Test
public void test4()
{
Map<String, Integer> map = new LinkedHashMap<String, Integer>();
for (int i = 0; i < 200; i++)
map.put("the " + i, i);
WordCountPro.writeOutput(map);
assertEquals(transformMapintoChar(map), readFileByChars("result.txt"));
}
@Test
public void test5()
{
Map<String, Integer> map = new HashMap<String, Integer>();
WordCountPro.writeOutput(map);
assertEquals(0, lineCount("result.txt"));
}
@Test
public void test6()
{
Map<String, Integer> map = new LinkedHashMap<String, Integer>();
for (int i = 0; i < 50; i++)
map.put("the " + i, i);
WordCountPro.writeOutput(map);
assertEquals(50, lineCount("result.txt"));
}
@Test
public void test7()
{
Map<String, Integer> map = new LinkedHashMap<String, Integer>();
for (int i = 0; i < 100; i++)
map.put("the " + i, i);
WordCountPro.writeOutput(map);
assertEquals(100, lineCount("result.txt"));
}
@Test
public void test8()
{
Map<String, Integer> map = new LinkedHashMap<String, Integer>();
for (int i = 0; i < 200; i++)
map.put("the " + i, i);
WordCountPro.writeOutput(map);
assertEquals(100, lineCount("result.txt"));
}
实在无法完成20个测试用例的编写,这一方面请老师在审查项目后理解。
单元测试截图:
小组贡献分
根据小组讨论结果,个人占小组贡献率为22%
扩展任务
代码规范:
主要参考邹老师的博客
地址:http://www.cnblogs.com/xinz/archive/2011/11/20/2255971.html
在写代码之前,组长先给我们声明了几点
- 变量名采用小驼峰
- { 换行
- 在运算符两旁和逗号后面加上空格
- 注释使用英文
- 较长的连续代码适当地加空行
这些主要针对代码的美观问题,让后来的人来看代码不会觉得很不舒服,自己在回审的时候也比较舒服
注释用英文,在邹老师的博客中也提到,
注释(包括所有源代码)应只用ASCII字符,不要用中文或其他特殊字符,它们会极大地影响程序的可移植性。
为此,我之前为了直观的中文最后push的时候都改成了英文,虽然英语不好导致用英文描述有些困难,但还是遵从代码规范的要求。
函数名的要求,在实现的时候,函数名都是功能的英文版的缩写,一是美观,而是能够直观表现函数的功能
成员属性的定义,为了调用的方便定义成静态方法,为了安全定义成私有类型。
对小组其他成员代码的评价
我评价的是成员王思哲的代码,他负责的主要功能是对输入文件的判断和对内容的提取。基本上满足了代码的规范要求,个人感觉可以改的有两处(强迫症):
- 将功能的所有语句,包括创建转化都写进try里面会比较好
- 循环体内只有一条语句,将两侧的括号删去会比较美观
静态工具
用的是findbugs
地址:http://findbugs.sourceforge.net/manual/eclipse.html
上图是找到的bug,因为自己的eclipse安装不上findbugs的插件,借用了组里成功安装的同学的截图。没有发现自己代码的bug,说明代码质量比较过关
高级任务
关于效率的问题,我所负责的部分,效率分析大概对map的遍历和转化上面,参考了一篇博客,地址:https://blog.csdn.net/zhangsify/article/details/52966094 是用不同的方法对map进行遍历,相关结论请移步。由于map的量达到很大数量级,相应结果差最大为40ms,自己的数据没有达到这个量级,差距很小,导致误差影响较大,因此以该博客的结果为最终结论。
关于开发,测试,质量之间的关系,就像该次作业中三个任务依次前进的关系。我们首先完成软件开发,即完成基本的功能实现,在代码编译通过的情况下,利用软件测试的各种方法来查找代码中的一些bug,让代码能够完成我们所需要的功能,最后再关注代码质量,尽量提高代码效率,减少用时等。
参考地址:
Java 读取map的方法:
https://blog.csdn.net/blueheart20/article/details/45173621
Java 写文件:
https://blog.csdn.net/hacker_Lees/article/details/78593799
Java map遍历的方法比较:
https://blog.csdn.net/zhangsify/article/details/52966094
Junit使用:
https://blog.csdn.net/andycpp/article/details/1327147/