第2周个人作业:WordCount

(1)文章开头给出Github项目地址:

https://github.com/liaotaiwei/Software-Quality-And-Testing/tree/master/wordCount

(2)填写PSP表格:

PSP2.1 PSP阶段 预估耗时(分钟) 实际耗时(分钟)
Planning 计划 120 60
· Estimate · 估计这个任务需要多少时间 两天 两天
Development 开发 240 240
·Analysis · 需求分析 (包括学习新技术) 60 55
· Design Spec · 生成设计文档 60 20
· Design Review · 设计复审 (和同事审核设计文档) 100 30
· Coding Standard · 代码规范 (为目前的开发制定合适的规范) 100 20
· Design · 具体设计 60 40
· Coding · 具体编码 100 240
· Code Review · 代码复审 30 30
· Test · 测试(自我测试,修改代码,提交修改) 240 240
Reporting 报告 120 60
· Test Report · 测试报告 60 40
· Size Measurement · 计算工作量 10 10
· Postmortem & Process Improvement Plan · 事后总结, 并提出过程改进计划 120 120
合计 两天 两天

(3)描述解题思路:

WordCount要求对程序设计语言源文件统计字符数、单词数、行数,统计结果以指定格式输出到默认文件中,以及其他扩展功能,并能够快速地处理多个文件。
首先实现四个基本功能:
返回文件 file.c 的字符数
返回文件 file.c 的单词总数
返回文件 file.c 的总行数
将结果输出到指定文件outputFile.txt
java的String类、File类自带的函数就够用,自己再加一些判断条件,比如是否读到文件末尾之类。
这个过程基本没遇到问题,唯一卡了一会的地方就是:关于用read()函数作循环判断条件的部分。我当时专门发了一篇随笔,链接在这

http://www.cnblogs.com/liaotaowei/p/8587699.html

大概就是说不能用read()!=-1判断,因为read()函数会每次判断都往下读一个,导致readline()无法读到行首字符。
然后实现三个扩展功能:
递归处理目录下符合条件的文件
返回更复杂的数据(代码行 / 空行 / 注释行)
停用词表,统计文件单词总数时,不统计该表中的单词
其中,递归处理很简单,首先判断是不是文件夹,是则调用函数自身继续递归处理,否则就调用之前编写好的getWC()函数,本质上是一个宽度优先遍历。
第二个拓展功能,返回更复杂的数据:设置一个标志用于区分/~/类注释和//类注释。遍历整行,寻找注释符号,遇到"/"就继续查找后面是否有“/”或者“”,若是“//”类注释直接注释行加一,若是“/”则标志改变,并且注释行数随着行的遍历一直加一,直到找到“*/”,再次改变标志。
停用词处理是直接遍历停用词文件得到。

(4)程序设计实现过程。

public static boolean isCommentLine(String s)//判断是不是注释行,遍历整行,寻找注释符号,并且对两种注释进行不同的处理

public static boolean isCommentLineEnd(String s)//遍历整行,寻找*/

public static boolean isSpaceLine(String s) //判断是否是空行

public static boolean isInStopList(String s)//判断是否在停用词表中

public static void parseStopList(File file) //读取停用词表

public static void getWC(File file) //判断,并计算各个需要的数据

public static void main(String[] args) //主函数,最后重定向回控制台

(5)代码说明。

public static void main(String[] args) throws IOException, ParseException {
//解析参数列表
for(int i = 0; i < args.length; i++){
if(args[i].equals("-c")){
cFlag = 1;
}
else if(args[i].equals("-w")){
wFlag = 1;
}
else if(args[i].equals("-l")){
lFlag = 1;
}
else if(args[i].equals("-a")){
aFlag = 1;
}
else if(args[i].equals("-s")){
sFlag = 1;
}
//读取停用词表
else if(args[i].equals("-e")){
//往后看一位
stopListPath = args[i + 1];
i++;
eFlag = 1;
//如果不是TXT文件,则警告出错
if(!stopListPath.endsWith(".txt")){
System.out.println("Error: No stop list!");
}
File stopFile = new File(stopListPath);
parseStopList(stopFile);
}
//读取输出路径
else if(args[i].equals("-o")){
//往后看一位
outputPath = args[i + 1];
i++;
if(!outputPath.endsWith(".txt")){
System.out.println("Error: No output file!");
}
}
//读取输入文件路径
else{
inputPath = args[i];
}
}
System.setOut(new PrintStream(new BufferedOutputStream(new FileOutputStream(outputPath)), true));
File file = new File(inputPath);
//如果是文件夹,则递归处理下面的文件
if(sFlag == 1) {
if (file.isDirectory()) {
//处理文件夹
LinkedList list = new LinkedList();
File[] files = file.listFiles();
//遍历路径,如果是
for (File pFile : files) {
if (pFile.isDirectory()) {
list.add(pFile);
} else {
getWC(pFile);
}
}
//不停从列表中弹出,如果是文件就getWC,本质上是一个宽度优先遍历
File tFile;
while (!list.isEmpty()) {
tFile = list.removeFirst();
files = tFile.listFiles();
for (File pFile : files) {
if (pFile.isDirectory()) {
list.add(pFile);
} else {
getWC(pFile);
}
}
}
}
}
else{
getWC(file);
}
//重定向回控制台
System.setOut(new PrintStream(new BufferedOutputStream(new FileOutputStream(FileDescriptor.out)), true));
}

(6)测试设计过程。
过程思考:

白盒测试法的覆盖标准有逻辑覆盖、循环覆盖和基本路径测试。其中逻辑覆盖包括语句覆盖、判定覆盖、条件覆盖、判定/条件覆盖、条件组合覆盖和路径覆盖。六种覆盖标准发现错误的能力呈由弱到强的变化:
1.语句覆盖每条语句至少执行一次。
2.判定覆盖每个判定的每个分支至少执行一次。
3.条件覆盖每个判定的每个条件应取到各种可能的值。
4.判定/条件覆盖同时满足判定覆盖条件覆盖。
5.条件组合覆盖每个判定中各条件的每一种组合至少出现一次。
6.路径覆盖使程序中每一条可能的路径至少执行一次。

单元测试(模块测试)是开发者编写的一小段代码,用于检验被测代码的一个很小的、很明确的功能是否正确。通常而言,一个单元测试是用于判断某个特定条件(或者场景)下某个特定函数的行为。例如,你可能把一个很大的值放入一个有序list 中去,然后确认该值出现在list 的尾部。或者,你可能会从字符串中删除匹配某种模式的字符,然后确认字符串确实不再包含这些字符了。

过程确定:
1.只有一个单词
2.有多个单词
3.单行注释
4.多行注释
5.单行空白行
6.多行空白
7.有停用词
8.递归处理多个文件
8.不指定输出文件 没有-o output.txt
9.指定输出文件 有-o output.txt
10.综合测试

测试用例:

测试结果:

具体测试文件见我的github,地址如下:

https://github.com/liaotaiwei/Software-Quality-And-Testing

(7)参考文献链接。
http://www.cnblogs.com/ningjing-zhiyuan/p/8563562.html
这是最初给我的需求说明,很多模糊的地方我就照着自己的理解做了。比如给出的测试文件,这个博客里全部给的是.c结尾,我就在判断条件里加了一个判断测试文件后缀是不是.c。结果后来听同学说,要求处理各种不同的文件,于是又重新编译,重新生成exe。希望需求能进一步明确吧。作业已经不少,需求还这么模糊,实在是造成了很大的不便。

posted @ 2018-03-20 16:27  廖泰薇  阅读(202)  评论(1编辑  收藏  举报