java统计词频算法_Java实现的词频统计——单元测试

前言:本次测试过程中发现了几个未知字符,这里将其转化为十六进制码对其加以区分。

1)保存统计结果的Result文件中显示如图:

8d3b22784747d91d8fc1accbbe124ad2.png

2)将其复制到eclipse环境下的切分方法StringTokenizer中却没有显示;

复制前:

b0aec782bae0ce67c895c2b2bb8d90e5.png

复制后:

4b225cdfdb20262736661850f681dd51.png

前后看似没有任何变化;

3)改动后的统计结果:

b3510b5c83a3f9ae6674755bcb8cb380.png

因此为了检测这个字符做了一个将其转化为十六进制码的小程序:

1 String t = "\0";2 String s = "\0";3 byte[] bbb =t.getBytes();4 int[] n = new int[bbb.length];5 for (int i = 0; i < n.length; i++) {6 n[i] = bbb[i] & 0xff;    //将每个字符的十六进制码保存到数组中7 }8 for (int j = 0; j < n.length; j++) {9 System.out.println(Integer.toString(n[j], 0x10));10 }11 System.out.println("-----------------");12 byte[] b =s.getBytes();13 int[] in = new int[b.length];14 for (int i = 0; i < in.length; i++) {15 in[i] = b[i] & 0xff;16 }17 for (int j = 0; j < in.length; j++) {18 System.out.println(Integer.toString(in[j], 0x10));19 }

运行结果如下:

62fa9172f318323d68651c52ca4fd15c.png

从结果可以看出,这个未知字符是由三个字符组成,而类似的难以识别的字符还有很多。

此外,在做单元测试之前还做了一项额外的测试——read()方法读取文件时单次读取的字符数量对效率的影响:

选取了从1-128、129-256、257-384、385-512四个范围,分别进行了测试。

总测试次数2560次,耗时10min左右,统计结果:

当取值在200左右时运行速率最快,平均值在210ms左右.

单元测试

对Java工程进行的单元测试,使用的工具为Eclipse集成的Juint4。

1.对FileProccessing类进行测试,测试其输出到控制台与输出到文件的结果与预期是否相同。Juint代码如下:

输出到控制台:这里用到了重定向输出,将要输出到控制台的字符串输出到缓冲区,并与预期结果进行比对。

1 @Test2 public void testFP() throwsException {3

4 final ByteArrayOutputStream outContent = newByteArrayOutputStream();5 System.setOut(newPrintStream(outContent));    //重定向输出,方便后面进行比对6 new FileProccessing("content.txt", 200);7 assertEquals(8 "~~~~~~~~~~~~~~~~~~~~\r\ncontent\r\ntotals of the words:6\r\nquantity of vocabulary:5\r\nvery——2\r\nenglish——1\r\nis——1\r\nmy——1\r\npoor——1\r\n~~~~~~~~~~~~~~~~~~~~\r\n",9 outContent.toString());10

11 }

输出到文件:生成实例后分别建立两个文件流,一个读取实际结果文件,一个读取预期结果文件,通过循环逐行比对。

1 public void testFPtoFile() throwsException{2 new FileProccessing("E:\\Test3\\Test1.txt");    //测试文件3 FileReader expect = new FileReader("E:\\Test3\\Expect.txt");    //用来保存期待的结果4 BufferedReader ep= newBufferedReader(expect);5 FileReader actual = new FileReader("Result.txt");    //实际的结果文件6 BufferedReader at = newBufferedReader(actual);7 String temp;8 while((temp = at.readLine()) != null){9 assertEquals(ep.readLine(),temp);    //对文件中内容逐行比较10 }11 at.close();12 actual.close();13 ep.close();14 expect.close();15 }

用例截图:

04bce6f7e9b048e059d64b97033ebe21.png

2a456e455577a57b5b20ed1e6d9d8ad9.png

单元测试结果:

73a815dfee2469ea5b27c10b09ae6f0a.png

代码覆盖率:覆盖率为72%,未覆盖到的部分为主函数中为用户提供输入的代码段。

56fc611eb99b3d79e9eca1ddd54242a5.png

2.对于上面的测试用例进行改进,对main()函数不同情况的的输入输出进行测试。Juint代码如下,大致分为四种情况:

1>由命令行传入参数:

1 @Test2 public void testMain1() throwsException {3 String[] test = { "E:\\Test3\\Test1.txt"};4 WordFrequencyCount.main(test);    //生成实例5

6 FileReader expect = new FileReader("E:\\Test\\Expect.txt");7 BufferedReader ep = newBufferedReader(expect);8 FileReader actual = new FileReader("Result.txt");9 BufferedReader at = newBufferedReader(actual);10

11 String temp;12 while ((temp = at.readLine()) != null) {13 assertEquals(ep.readLine(), temp);14 }15

16 at.close();17 actual.close();18 ep.close();19 expect.close();20 }

2>传入参数为文件夹时:

1 @Test2 public void testMain2() throwsException {3 String[] test = { "E:\\Test3"};    //文件夹中内容为Test1.txt4 WordFrequencyCount.main(test);5

6 FileReader expect = new FileReader("E:\\Test\\Expect.txt");7 BufferedReader ep = newBufferedReader(expect);8 FileReader actual = new FileReader("Result.txt");9 BufferedReader at = newBufferedReader(actual);10

11 String temp;12 while ((temp = at.readLine()) != null) {13 assertEquals(ep.readLine(), temp);14 }15

16 at.close();17 actual.close();18 ep.close();19 expect.close();20

21 }

3>由控制台重定向输入:这里运用了重定向输入,并且将String转化为输入流。

1 @Test2 public void testMain3() throwsException {3 String[] test ={};4 String str = "< E:\\Test3\\Test1.txt\n";5 ByteArrayInputStream instr = newByteArrayInputStream(str.getBytes());    //将String转化为输入流6

7 System.setIn(instr);    //重定向输入8 WordFrequencyCount.main(test);9

10 FileReader expect = new FileReader("E:\\Test\\Expect.txt");11 BufferedReader ep = newBufferedReader(expect);12 FileReader actual = new FileReader("Result.txt");13 BufferedReader at = newBufferedReader(actual);14

15 String temp;16 while ((temp = at.readLine()) != null) {17 assertEquals(ep.readLine(), temp);18 }19

20 at.close();21 actual.close();22 ep.close();23 expect.close();24 }

4>由控制台输入文件名及内容:这一部分使用了重定向输入和输出;由于main()函数中为了方便用户使用,会有输出作为引导,因此在比对时要把这部分输出也纳入考虑。

1 @Test2 public void testMain4() throwsException {3 String[] test ={};4 String str = "content\nMy English is very very poor.\n";5 ByteArrayInputStream instr = newByteArrayInputStream(str.getBytes());6

7 System.setIn(instr);8

9 final ByteArrayOutputStream outContent = newByteArrayOutputStream();10 System.setOut(newPrintStream(outContent));11 WordFrequencyCount.main(test);12 assertEquals(13 "请输入文件名:\r\n请输入内容,结尾以回车后ctrl+z结束:\r\n~~~~~~~~~~~~~~~~~~~~\r\ncontent\r\ntotals of the words:6\r\nquantity of vocabulary:5\r\nvery——2\r\nenglish——1\r\nis——1\r\nmy——1\r\npoor——1\r\n~~~~~~~~~~~~~~~~~~~~\r\ntime:1ms\r\n",14 outContent.toString());15 }        //要考虑到main()函数中面向用户的输出

(为了方便测试,这一部分用例与之前相同,这里不再展示)

单元测试结果:

7231b773f04ba4fb84a38a3302fd58a2.png

代码覆盖率:覆盖率为94%,加入了对于面向用户的输入输出的测试。仍有未覆盖到的代码,主要是抛出异常、异常处理、异常检测部分的代码。

f7b23d4c72dfccc4e9bfafbe42cf9a76.png

通过此次单元测试了解到:System.out.println()与System.out.print()方法差别不仅仅在于行末多了换行符\n,而是\r\n。同时通过这次单元测试发现了原程序中的bug:用read()方法读取文件时用来保存结果的char[]不会自动清空,而是以覆盖的方式读取字符,因此会导致统计结果有误。

代码地址:

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值