软件质量与测试--第二周作业 WordCount

软件质量与测试 第二周作业 WordCount

Github地址:

https://github.com/Hu-Peking/WordCount

 

PSP2.1: 

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

解题思路:

  1、将程序的功能需求分为基础功能和拓展功能,按先后顺序分别实现两部分的内容;

  2、先在IDE中实现对电脑中指定目录下的文件的读写操作;

  3、编写程序,实现可以在Main函数的调用下分别正确运行各个基础功能;

  4、编写程序,实现在终端执行该程序时,程序可以获取到终端输入的全部参数,并能对终端所在的目录下的文档进行读写;

  5、调整Main函数中对各个功能的调用机制,使得在终端输入相应的参数时,程序可以正常执行所对应的功能;

  6、确定程序可以正确运行所有的基础功能后,把工程打包成.jar文件,再将.jar文件转换成.exe文件,在终端中运行.exe文件,确保.exe可以正确执行所有基础功能;

  7、基于实现基础功能的程序,进行扩展功能的程序的编写,完成所有的扩展功能;

  8、确定程序可以正确运行所有功能后,把工程打包成.jar文件,再将.jar文件转换成.exe文件,在终端中运行.exe文件,确保.exe可以正确执行所有功能;

 

  本工程的参考资料都是通过百度所查找的,均是博客

  查阅资料:

  http://blog.csdn.net/u012325167/article/details/50856515

  http://blog.csdn.net/chengzhaoan2010/article/details/78344791

 

程序设计实现过程:

  程序包含三个类,分别为Main、Action、Count和FileUtils

  Main:程序的主函数类,实现整个程序的所有功能的调用,其中含有以下方法:

    main():作为主方法。

  Action:实现要执行功能的判断、各种统计功能的调用和最后的信息输出的功能,其中含有以下方法:

    judges(String[] commands):命令分析函数,对终端中传入的参数进行判断,统计需要执行的功能;

    do_thing(String[] orders):对需要执行的功能进行调用;

    write(String[] write_content):对write_content中的内容进行打印;

  Count:此类为本工程的主体,完成了-c, -w, -l, -o, -a, -e这些功能的实现,其中含有以下方法:

    c(File file):统计文件中的字符数;

    w(File file):统计文件的单词数;

    l(File file):统计文件的行数;

    a(File file):统计文件的代码行、空行和注释行的行数;

    we(File file, File stop):统计文件中除去停用词表中的停用词后,剩余的单词总数;

  FileUtils:此类实现了递归处理目录下符合条件的文件,其中含有以下方法:

    getFiles(File dir):递归处理dir目录下的所有文件,对以.c结尾的文件进行命令行中的操作;

 

代码说明:

主函数:建立Action类的实例ac,通过ac调用Action中的命令分析、结果打印和功能调用这些方法;

 1 public static void main(String[] args) {
 2 
 3         String[] commands = new String[10];
 4         String print_content = null;
 5         String[] lastone = new String[2];
 6 
 7         Action ac = new Action();
 8 
 9         commands = ac.judges(args);
10 
11         if (commands[6].equals("true") && commands[7].endsWith(".c")) {
12             FileUtils fu = new FileUtils(commands);
13             print_content = fu.all_content;
14         } else {
15             print_content = Action.do_thing(commands);
16         }
17 
18 
19         lastone[0] = commands[8];
20         lastone[1] = print_content;
21 
22         ac.write(lastone);
23 
24     }

命令分析函数:对args[]字符串数组中的参数进行判断,依次获取args[]中的每一个参数并将其与"-c", "-w", "-l", "-o", "-a", "-e", "-s"这7个字符串进行比较,决定程序需要对文件执行-c, -w, -l, -o, -a, -e, -s中的哪些功能;此外通过判断args[]中是否存在相等的字符串判断命令行输入是否有误,选取以".txt"和".c"结尾的,获取.c和.txt文件的文件名,最终将判断后所得的结果返回;

  1 public String[] judges(String[] commands) {
  2 
  3         String[] output = new String[10];
  4 
  5 //        ArrayList<Object> output = new ArrayList<Object>();
  6 
  7         boolean error = false;
  8         boolean l = false;       //1
  9         boolean w = false;       //2
 10         boolean c = false;       //3
 11         boolean o = false;       //4
 12         boolean a = false;       //5
 13         boolean e = false;       //6
 14         boolean s = false;       //7
 15 
 16         String in_file = null;   //8
 17         String out_file = null;  //9
 18         String stop_file = null; //10
 19 
 20         String path = null;
 21 
 22         //保证输入的参数无重复
 23         for (int i = 0; i < commands.length - 1; i++) {
 24             for (int j = i + 1; j < commands.length; j++) {
 25                 if (commands[i].equals(commands[j])) {
 26                     error = true;
 27                     break;
 28                 }
 29             }
 30             if (error) {
 31                 break;
 32             }
 33         }
 34 
 35         if (!error) {
 36             for (int i = 0; i < commands.length; i++) {
 37                 if (commands[i].equals("-l")) {
 38                     l = true;
 39                 } else if (commands[i].equals("-w")) {
 40                     w = true;
 41                 } else if (commands[i].equals("-c")) {
 42                     c = true;
 43                 } else if (commands[i].equals("-a")) {
 44                     a = true;
 45                 } else if (commands[i].equals("-e")) {
 46                     e = true;
 47                     i = i + 1;
 48                     stop_file = commands[i];
 49                     if (!stop_file.contains(".txt")) {
 50                         error = true;
 51                         break;
 52                     }
 53                 } else if (commands[i].equals("-o")) {
 54                     o = true;
 55                     i = i + 1;
 56                     out_file = commands[i];
 57                     if (!out_file.endsWith(".txt")) {
 58                         error = true;
 59                         break;
 60                     }
 61                 } else if (commands[i].equals("-s")) {
 62                     s = true;
 63                 } else if (commands[i].endsWith(".c")) {
 64                     in_file = commands[i];
 65                 } else {
 66                     error = true;
 67                     break;
 68                 }
 69             }
 70 
 71 
 72             File directory = new File("");
 73             try {
 74                 path = directory.getAbsolutePath();
 75             } catch (Exception e1) {
 76                 e1.printStackTrace();
 77             }
 78 
 79 
 80             //确定要写的文件
 81             if (!o) {
 82                 out_file = "result.txt";
 83             }
 84 
 85 
 86             //确定停用词文件
 87             File file_stop = null;
 88             if (e) {
 89                 //设置停用词表
 90                 file_stop = new File(path + "/" + stop_file);
 91 
 92                 if (!file_stop.exists()) {
 93                     error = true;
 94                     System.out.println("停用词表不存在!");
 95                     System.exit(0);
 96                 }
 97             }
 98 
 99             if (l) {
100                 output[0] = "true";
101             } else {
102                 output[0] = "false";
103             }
104 
105             if (w) {
106                 output[1] = "true";
107             } else {
108                 output[1] = "false";
109             }
110 
111             if (c) {
112                 output[2] = "true";
113             } else {
114                 output[2] = "false";
115             }
116 
117             if (o) {
118                 output[3] = "true";
119             } else {
120                 output[3] = "false";
121             }
122 
123             if (a) {
124                 output[4] = "true";
125             } else {
126                 output[4] = "false";
127             }
128 
129             if (e) {
130                 output[5] = "true";
131             } else {
132                 output[5] = "false";
133             }
134 
135             if (s) {
136                 output[6] = "true";
137             } else {
138                 output[6] = "false";
139             }
140 
141             output[7] = path + "/" + in_file;
142             output[8] = path + "/" + out_file;
143             output[9] = path + "/" + stop_file;
144 
145 
146         } else {
147             System.out.println("命令行输入有误!");
148             System.exit(0);
149         }
150         return output;
151     }

结果输出函数:在调用该函数时获取要打印到.txt文件中的内容,通过java.IO.File类的方法将结果打印到.txt文件中;

 1 public void write(String[] write_content) {
 2 
 3         //write_content[0] file  write_content[1] content
 4 
 5         //向文件中写入内容
 6 
 7         File write_file = new File(write_content[0]);
 8 
 9         if (!write_file.exists()) {
10             try {
11                 write_file.createNewFile();
12             } catch (Exception e1) {
13                 e1.printStackTrace();
14             }
15         }
16         try {
17 
18             FileWriter fw = new FileWriter(write_file);
19             BufferedWriter bufw = new BufferedWriter(fw);
20             bufw.write(write_content[1]);
21             bufw.close();
22             fw.close();
23         } catch (Exception e1) {
24             e1.printStackTrace();
25         }
26         System.out.println("Succeed!");
27     }

 

递归处理函数:实现-s操作,以wc.exe所在的文件夹为起点,利用深度优先搜索,遍历wc.exe文件夹所在的目录下所有后缀名为.c的文件,并对这些文件依次进行命令行所输入的操作,具体操作如下:

    1、遍历wc.exe所在的文件夹中的每个文件,判断其是否为文件或是文件夹;

    2、若为文件则对其进行命令行所输入的操作;

    3、若为文件夹则获取其中所有文件,并对每一个文件进行1中操作;

 1 public void getFiles(File dir) {
 2         if (dir.exists()) {
 3             //判断是否是目录
 4             if (dir.isDirectory()) {
 5                 File[] files = dir.listFiles();
 6 
 7                 for (File file : files) {
 8                     getFiles(file);
 9                 }
10             } else {
11                 String inFile = dir.getAbsolutePath();
12                 if (inFile.endsWith(".c")) {
13                     arg[7] = inFile;
14                     all_content = all_content + Action.do_thing(arg) + "\n";
15                     System.out.print("\n");
16                 }
17             }
18         }
19     }

-c, -w, -l, -o, -a, -e等的操作较为雷同,故选取-w所对应的函数进行举例;

单词统计:实现-w的操作,先获取读入文件的所有内容,再调用split()函数在" "和","处对所有内容进行分割,最后统计分割得到的字符串数组的长度,即为该文件中的单词数;

 1 public int w(File file) {
 2         //单词数
 3         int word_num = 0;
 4 
 5         //文本的全部内容
 6         String content = "";
 7 
 8         //file存在,读取内容
 9         if (file.exists()) {
10             try {
11                 FileReader fr = new FileReader(file);
12 
13                 BufferedReader bufr = new BufferedReader(fr);
14                 String s = null;
15 
16                 //获取文本全部内容
17                 while ((s = bufr.readLine()) != null) {
18                     content = content + s;
19                 }
20                 bufr.close();
21                 fr.close();
22 
23                 String[] words = content.split("[ ]+|[,]+");
24                 /*for (int i = 0; i < words.length; i++) {
25                     System.out.println(i + words[i]);
26                 }*/
27                 //获取单词数
28                 word_num = words.length;
29 //                System.out.println(word_num);
30                 System.out.println(file.getName() + ",单词数:" + word_num);
31             } catch (Exception e1) {
32                 e1.printStackTrace();
33             }
34         } else {
35             word_num = -1;
36             System.out.println("文件不存在!");
37         }
38         return word_num;
39     }

 

测试设计过程:

测试中本着用例覆盖所有分支的目的进行设计

测试用例如下所示: 

 1 //下面测试-c字符统计功能
 2 if while else end
 3 
 4 
 5 //下面测试-w的单词统计功能
 6 interest ing
 7 interest
 8 ing
 9 
10 
11 //下面测试-a的空行/代码行/注释行的统计功能
12 //空行测试
13 
14  }
15 t
16 
17 //代码行测试
18 if(){
19 } else if(){
20 } else{
21 }
22 
23 //注释行测试
24 s//
25 //
26      //
27 
28 
29 //下面测试-e的排除停用词表中单词的统计功能
30 typedef struct {
31     int startvex;
32     int endvex;
33     int length;
34 } edge;
35 edge T[M];
36 
37 void main() {
38     int dist[N][N] = {{0,   6, MAX,  7,  MAX},
39                       {MAX, 0,   5,  8,  -4},
40                       {MAX, -2,  0, MAX, MAX},
41                       {MAX, MAX, -3, 0,  9},
42                       {2,   MAX, 7, MAX, 0}};//图的邻接矩阵
43     int d[N];
44     int num = 0;
45     num = BellmanFord(dist, d, 0);//计算下标为0的顶点到其它顶点的距离,num用于统计边数
46     for (int i = 0; i < N; i++)//打印到各个顶点之间的距离
47         printf("%d ", d[i]);
48     printf("\n");
49     for (int j = 0; j < num; j++)//打印考虑过的边
50         printf("start=%d,end=%d,lenth=%d\n", T[j].startvex, T[j].endvex, T[j].length);
51 }

终端命令行输入:

 1 //单个功能测试
 2 wc.exe -l file.c
 3 wc.exe -c file.c
 4 wc.exe -w file.c
 5 wc.exe -a file.c
 6 wc.exe -o out.txt
 7 
 8 //组合功能测试
 9 wc.exe -l -c file.c
10 wc.exe -l -w file.c
11 wc.exe -l -a file.c
12 wc.exe -c -w file.c
13 wc.exe -c -a file.c
14 wc.exe -w -a file.c
15 
16 wc.exe -l -w file.c -e stop.txt
17 wc.exe -c -w file.c -e stop.txt
18 wc.exe -w -a file.c -e stop.txt
19 
20 wc.exe -l -c -w -a file.c -e stop.txt
21 
22 wc.exe -l -c -w -a file.c -e stop.txt -o out.txt
23 
24 wc.exe -l -c -w -a -s *.c -e stop.txt
25 wc.exe -l -c -w -a -s *.c -e stop.txt -o out.txt
26 
27 
28 //错误测试
29 //无读取的文件
30 wc.exe -l -c
31 wc.exe -l -w
32 wc.exe -l -a
33 wc.exe -c -w
34 wc.exe -c -a
35 wc.exe -w -a
36 
37 //有-e,但无停用词表文件名
38 wc.exe -l -w file.c -e
39 wc.exe -c -w file.c -e
40 wc.exe -w -a file.c -e
41 
42 //有-o,但无输出文件名
43 wc.exe -l -c -w -a file.c -e stop.txt -o
44 wc.exe -l -c -w -a -s *.c -e stop.txt -o
45 
46 //有-s,但无"*.c"
47 wc.exe -l -c -w -a -s -e stop.txt
48 wc.exe -l -c -w -a -s -e stop.txt -o out.txt

在终端中输入上述测试命令后,程序可以正常运行,且按我自己对需求的理解,运行输出均无误。

此外,在BIN文件夹中加入了.bat的测试脚本文件,双击他运行,通过对控制台的输出的对比,也可进行测试。

 

参考文献链接:

Git教程 - 廖雪峰的官方网站

https://www.liaoxuefeng.com/wiki/0013739516305929606dd18361248578c67b8067c8c017b000

java获取当前路径的几种方法 - CSDN博客

http://blog.csdn.net/chengzhaoan2010/article/details/78344791

java.io.File类基本使用——遍历某路径的所有文件夹及文件 - CSDN博客

http://blog.csdn.net/u012325167/article/details/50856515

手把手教你如何把java代码,打包成jar文件以及转换为exe可执行文件 - CSDN博客

http://blog.csdn.net/sunkun2013/article/details/13167099

posted @ 2018-03-20 23:57  Haonan_Hu  阅读(288)  评论(2编辑  收藏  举报