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

GitHub: https://github.com/inverai/TestHome

 

PSP:

PSP2.1PSP 阶段预估耗时 (分钟)实际耗时 (分钟)
Planning 计划 25 20
· Estimate · 估计这个任务需要多少时间 25 20
Development 开发 230 270
· Analysis · 需求分析 (包括学习新技术) 20 30
· Design Spec · 生成设计文档 0 0
· Design Review · 设计复审 (和同事审核设计文档) 0 0
· Coding Standard · 代码规范 (为目前的开发制定合适的规范) 10 15
· Design · 具体设计 30 35
· Coding · 具体编码

120

 

130
· Code Review · 代码复审 20 20
· Test · 测试(自我测试,修改代码,提交修改) 30 40
Reporting 报告 60 70
· Test Report · 测试报告 10 10
· Size Measurement · 计算工作量 10 10
· Postmortem & Process Improvement Plan · 事后总结, 并提出过程改进计划 40 50

 

合计 315 360

 

解题思路:

    1. 了解JAVA命令行的使用与JAVAC的使用;(网上教程)

    2.  考虑基本功能的实现;

        基础: 

            <1.>  需要学习JAVA文件的操作和输入输出流的操作,(具体参考网上教程即可)

              <2. > 需要 了解动态数组的基本操作和String类的基本方法;

        功能:

            <1.>C文件字符数统计,(需要考虑JAVA换行与否, JAVA换行字符为/n + /r 算作两个字符, 需要做处理)

            <2.> 单词总数,(一行一行处理, 利用String类的split来划分出单词,进行统计即可)

            <3.> 总行数,   ( 按行读取时统计即可,可以按情况处理空行是否计算入内)

            <4.> 是否输出到文本,(将处理结果格式化为字符串,利用ArrayList存储, 然后设置一个flag即可, 如果在命令行找到 -o参数则遍历打印ArrayList即可)

    3. 扩展功能的实现:

        基础:

            <1. > File类的基本方法;

            <2. > String类的方法;

            <3.> HashMap的使用;

        功能: 

            <1. >递归处理复合目录下符合条件文件; (解析输入路径,提取目录和 文件格式,然后匹配合适文件名, 再遍历处理即可)

            <2.> 返回更复杂的数据统计(代码行、空行、注释行);   (根据要求写出条件判断、然后统计即可);

            <3.> 停用词表去除统计  ;  (将停用词表放入HashMap,在统计单词的时候获取到停用词即不统计即可);

    

    4. 高级功能:

        基础:  

            <1.> Swing编程;

        功能:  

            <1.> 通过图形界面选择文件输出统计信息; (使用JFrame 和 ActionListener 即可);

    5. 测试功能:

            <1.> 根据课程提供的测试用例来确认功能的基本实现;

            <2.> 自己设计测试用例来测试细节实现;

    6. 参数格式:

            <1.>  // Format: ----- "filename.c" -e "stop.txt" -o "func_output.txt"

            <2.> // Format: ----- "filename.c" -o "func_output.txt"

            <3.> // Format: ----- "filename.c" -e "stop.txt"

            <4.> // Format: ---- "filename.c"

  

程序设计实现

     1. 本程序主要包括一个Test类以及一个FileChooser类,  统计参数的存储全部使用 类的私有变量 HashMap来存储, 功能的实现通过函数来切分;

     2. 基本结构:

        

 

      3.  代码说明:

        <1.> 初始化参数和功能的选择

 

 

public static void main(String[] args) throws Exception{

        Test test = new Test();
        String stop_name, filename, output_name;

        if(args[0].equals("-o") && args.length == 2) {
            throw new Exception("Illegal Parameters");
        }

        for(int i = 0; i < args.length; i++) {
            test.map_inst.put(args[i], i);
            System.out.println(args[i]);
        }

        if(test.map_inst.get("-x") != null) {
            FileChooser chooser = new FileChooser();
            filename = chooser.filepath;
            test.map_inst.put("-c" , 1);
            test.map_inst.put("-w" , 2);
            test.map_inst.put("-l" , 3);
            test.map_inst.put("-a" , 4);
            test.map_inst.put("-o" , 5);
            test.process(filename, "../stoplist.txt", "../output.txt");
        } else {
            // get parameters
            // Format:    ----- "filename.c" -e "stop.txt" -o "func_output.txt"
            if(test.map_inst.get("-e") != null && test.map_inst.get("-o") != null){
                int pos = test.map_inst.get("-e");
                stop_name = args[pos + 1];
                filename = args[pos - 1];
                output_name = args[pos + 3];
            }else if(test.map_inst.get("-o") != null){
                // Format:    ----- "filename.c" -o "func_output.txt"
                stop_name = null;
                int cond = test.map_inst.get("-o");
                output_name = args[cond + 1];
                filename = args[cond - 1];
            }else if(test.map_inst.get("-e") != null){
                // Format:    ----- "filename.c" -e "stop.txt"
                output_name = null;
                int pos = test.map_inst.get("-e");
                stop_name = args[pos + 1];
                filename = args[pos - 1];
            }else {
                // Format:     ---- "filename.c"
                filename = args[args.length - 1];
                output_name = null;
                stop_name = null;
            }

            if(test.map_inst.get("-s") != null){
                String dictName = args[args.length - 1];
                int index = dictName.indexOf('*');
                String dict = dictName.substring(0, index);
                String file_pattern = dictName.substring(index + 1);
                File file = new File(dict);
                if(file.exists()) {
                    File files[] = file.listFiles();
                    for(File file1: files) {
                        if(file1.getName().contains(file_pattern)) {
                            test.process(file1.getAbsolutePath(), stop_name, output_name);
                        }
                    }
                }
            }else {
                test.process(filename, stop_name, output_name);
            }

        }
    }

      <2.> 具体不同输出结果的获取

      

public void process(String filename, String stop_name, String output_name) throws Exception{
        if(map_inst.get("-c") != null || map_inst.get("-w") != null || map_inst.get("-l") != null) {
            func_element(new BufferedReader(new InputStreamReader(new FileInputStream(filename))));
            if(map_inst.get("-c") != null)
                list.add(filename + ", char count:" + map.get("count_char") + "\n");
            if(map_inst.get("-w") != null)
                list.add(filename + ",word count:" + map.get("count_word") + "\n");
            if(map_inst.get("-l") != null)
                list.add(filename + ",line count:" + map.get("count_line") + "\n");
        }
        if(map_inst.get("-a") != null) {
            func_extend(new BufferedReader(new InputStreamReader(new FileInputStream(filename))));
            list.add(filename + ",blank lines count:" + map.get("count_null") + "\n");
            list.add(filename + ",Note lines count:" + map.get("count_note") + "\n");
            list.add(filename + ",Code lines count:" + map.get("count_code") + "\n");
        }
        if(map_inst.get("-e") != null) {
            BufferedReader stop = new BufferedReader(new InputStreamReader(new FileInputStream(stop_name)));
            String line = null;
            while((line = stop.readLine()) != null) {
                if (line.length() == 0) {
                    continue;
                }
                String str[] = line.trim().split(" |,");
                for(int j = 0; j < str.length; j++) {
                    map_stop.put(str[j], 10);
                }
            }
            func_stop(new BufferedReader(new InputStreamReader(new FileInputStream(filename))));
            list.add(filename + ",word count(stop_list):" + map.get("count_word_stop") + "\n");
        }

        if(map_inst.get("-o") != null) {
            func_output(output_name);
        }
    }

      <3.> 基本功能的实现

      

    public void func_element(BufferedReader br) throws Exception{
        int count_char = 0;
        int count_line = 0;
        int count_word = 0;
        String line = null;
        while((line = br.readLine()) != null) {
            if(line.length() == 0){
                continue;
            }
            count_char += line.length();
            count_word += line.trim().split(" |,").length;
            count_line++;
        }
        if(count_line == 1) {
            map.put("count_char", count_char);
        } else{
            map.put("count_char", count_char - (count_line - 1) * 2);
        }
        map.put("count_line", count_line);
        map.put("count_word", count_word);
    }

      <4.> 扩展功能的实现

 

    public void func_extend(BufferedReader br) throws Exception{
        int count_null = 0;
        int count_note = 0;
        int count_code = 0;
        boolean con_note = false;
        String line = null;
        while((line = br.readLine()) != null) {
            String trim = line.trim();
            if(true == con_note && trim.charAt(0) == '*' && trim.charAt(1) == '/') {
                con_note = false;
            }
            if(con_note) {
                count_note++;
            }

            if(trim.length() <= 1){
                count_null++;
            }else if(trim.charAt(0) == '/' && trim.charAt(1) == '/') {
                count_note++;
            }else if(trim.length() >= 3) {
                if(trim.charAt(0) == '}' && trim.charAt(1) == '/' && trim.charAt(2) == '/') {
                    count_note++;
                }
            } else if(trim.charAt(0) == '/' && trim.charAt(1) == '*') {
                con_note = true;
                count_note++;
            } else {
                    count_code++;
            }
            if(true == con_note && trim.charAt(trim.length() - 2) == '*' && trim.charAt(trim.length() - 1) == '/') {
                con_note = false;
            }
        }
        map.put("count_null", count_null);
        map.put("count_note", count_note);
        map.put("count_code", count_code);
    }

      <5.> 高级功能的实现

        

if(test.map_inst.get("-x") != null) {
            FileChooser chooser = new FileChooser();
            filename = chooser.filepath;
            test.map_inst.put("-c" , 1);
            test.map_inst.put("-w" , 2);
            test.map_inst.put("-l" , 3);
            test.map_inst.put("-a" , 4);
            test.map_inst.put("-o" , 5);
            test.process(filename, "../stoplist.txt", "../output.txt");

   4. 测试过程

        <1.> 在开发过程中根据老师提供的测试用例开发,全部通过;

        <2.> 自己设计测试用例进行测试,将结果输出至output.txt;测试的高风险点包括代码中包含分支判定及循环的位置,在测试中采用的语句覆盖的方法覆盖到了所有程序代码语句,用以应对高风险点。

        <3.> 个别测试样例:

            (1) test.exe -w -c filename.c -o func_output.txt

            (2) test.exe -w  filename.c -e stop.txt

               (3)  test.exe -w -c filename.c

            (4)  test.exe -w -l -s filename.c -o func_output.txt

                                           (5) test.exe -w -c -l -s filename.c -e stop.txt -o func_output.txt

            测试样例通过测试。

   5. 参考文献

        https://www.cnblogs.com/jiqing9006/p/6231290.html    JAVA文件操作与输入输出流

        http://blog.csdn.net/chenqk_123/article/details/49304469   java指定目录下递归读取文件

        https://www.cnblogs.com/dongrilaoxiao/p/6688107.html    JAVABufferReader使用

        https://www.cnblogs.com/panxuejun/p/5958875.html       JAVA的HashMap使用

posted @ 2018-03-20 13:20  SuiFengSuiXing  阅读(192)  评论(2编辑  收藏  举报