• 软工实践寒假作业(2/2)


    这个作业属于哪个课程 2020春|S班 (福州大学)
    这个作业要求在哪里 软工实践寒假作业(2/2)
    这个作业的目标 1.学习如何使用GitHub
    2.编写属于自己的代码规范
    3.根据需求文档编写疫情统计程序
    4.学习并应用单元测试
    5.根据要求撰写博客
    作业正文 https://www.cnblogs.com/GaogaoBlog/p/12307853.html
    其他参考文献 邹欣老师博客:
    1 软件工程概论
    2 工程师能力评估与发展
    3 分析方法和设计方法
    来自CSDN:
    JAVA单元测试的用法和要点(入门篇)
    FileReader读取文件的三种方式

    目录

    一.GitHub仓库

    [GaogaoHub](https://github.com/GaogaoHub)

    二、PSP表格

    PSP2.1 Personal Software Process Stages 预估耗时(分钟) 实际耗时(分钟)
    Planning 计划 60 57
    Estimate 估计这个任务需要多少时间 60 57
    Development 开发 940 967
    Analysis 需求分析 (包括学习新技术) 60 90
    Design Spec 生成设计文档 50 56
    Design Review 设计复审 40 49
    Coding Standard 代码规范 (为目前的开发制定合适的规范) 30 70
    Design 具体设计 100 146
    Coding 具体编码 420 336
    Code Review 代码复审 60 52
    Test 测试(自我测试,修改代码,提交修改) 120 168
    Reporting 报告 120 122
    Test Repor 测试报告 20 35
    Size Measurement 计算工作量 20 25
    Postmortem & Process
    Improvement Plan
    事后总结, 并提出过程改进计划 80 62
    合计 1120 1146

    三、我的解题思路

    四、具体设计





    五、代码说明

    1.main() ``` public static void main(String[] args) { // 命令输入格式检查 if (!ListCommand.checkInput(args)) { System.out.println("命令输入格式错误,退出程序"); System.exit(1); } //初始化命令和数据表 ListCommand aListCommand = new ListCommand(args); Statistic aStatistic = new Statistic(); //检查命令是否符合要求 aListCommand.checkCommand(aStatistic); //初始化日志目录 LogFiles aLogFiles = new LogFiles(aListCommand.arguments[0].value); //读取日志 aLogFiles.readFiles(aListCommand.arguments[2].value, aStatistic); //输出统计结果 aStatistic.outPutFile(aListCommand.arguments[1].value, (TypeArgument) aListCommand.arguments[3], (ProvinceArgument) aListCommand.arguments[4]); //完成 System.out.println("运行成功!统计数据存放在"+aListCommand.arguments[1].value); } ```

    2.ListCommand构造函数

    ListCommand(String[] strs) {
            // TODO Auto-generated constructor stub
            name = strs[0];
            arguments = new BaseArgument[5];
            arguments[0] = new LogArgument("-log");
            arguments[1] = new OutArgument("-out");
            arguments[2] = new DateArgument("-date");
            arguments[3] = new TypeArgument("-type");
            arguments[4] = new ProvinceArgument("-province");
    
            // 分析命令行 赋值arguments
            for (int i = 1, k = 0; i < strs.length && k < 5; ++i) {
                int n = 1;
                // 经检查strs[1]一定是参数
                ++i;
                while (!strs[i].startsWith("-")) {
                    ++n;
                    ++i;
                    if (i == strs.length) {
                        break;
                    }
                }
                --i;
                // 创建赋值BaseArgument的string数组
                String[] argStrings = new String[n];
                for (int j = 0; j < n; ++j) {
                    argStrings[j] = strs[i - n + 1 + j];
                }
    
                // 赋值BaseArgument[]
                switch (argStrings[0]) {
                case "-log":
                    arguments[0] = new LogArgument(argStrings);
                    break;
                case "-out":
                    arguments[1] = new OutArgument(argStrings);
                    break;
                case "-date":
                    arguments[2] = new DateArgument(argStrings);
                    break;
                case "-type":
                    arguments[3] = new TypeArgument(argStrings);
                    break;
                case "-province":
                    arguments[4] = new ProvinceArgument(argStrings);
                    break;
                default:
                    ;
                }
            }
        }
    

    3.LogFiles构造函数,其中目录下的日志文件用可以排序的TreeSet存放,并重载Comparator的compare()

    LogFiles(String path) {
            File logFile = new File(path);
            File[] temp = logFile.listFiles();
            files = new TreeSet<File>(new Comparator<File>() {
                @Override
                // 文件按日期排序 重写匿名内部类Comparator的compare()
                public int compare(File f0, File f1) {
                    // TODO Auto-generated method stub
                    String name0 = f0.getName();
                    String name1 = f1.getName();
                    // 按年份月份日期依次比较时间前后
                    if (Integer.parseInt(name0.substring(0, 4)) < Integer.parseInt(name1.substring(0, 4))) {
                        return -1;
                    }
                    if (Integer.parseInt(name0.substring(0, 4)) > Integer.parseInt(name1.substring(0, 4))) {
                        return 1;
                    }
                    if (Integer.parseInt(name0.substring(5, 7)) < Integer.parseInt(name1.substring(5, 7))) {
                        return -1;
                    }
                    if (Integer.parseInt(name0.substring(5, 7)) > Integer.parseInt(name1.substring(5, 7))) {
                        return 1;
                    }
                    if (Integer.parseInt(name0.substring(8, 10)) < Integer.parseInt(name1.substring(8, 10))) {
                        return -1;
                    }
                    if (Integer.parseInt(name0.substring(8, 10)) > Integer.parseInt(name1.substring(8, 10))) {
                        return 1;
                    }
                    return 0;
                }
    
            });
            for (int i = 0; i < temp.length; ++i) {
                files.add(temp[i]);
            }
    
            lastDate = files.last().getName().substring(0, 10);
        }
    

    4.LogFiles.outPutFile(String path, TypeArgument types, ProvinceArgument provinces):根据-type -province参数值过滤数据再输出

    void outPutFile(String path, TypeArgument types, ProvinceArgument provinces) {
            try {
                // 打开out文件
                BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(path), "UTF-8"));
                String outline;
                // 处理type参数值 用boolean[]分别表示是否输出四种类型
                boolean[] typetemp = { false, false, false, false };
                if (types.value.equals("valuelist")) {
                    for (String temp : types.valueList) {
                        switch (temp) {
                        case "ip":
                            typetemp[0] = true;
                            break;
                        case "sp":
                            typetemp[1] = true;
                            break;
                        case "cure":
                            typetemp[2] = true;
                            break;
                        case "dead":
                            typetemp[3] = true;
                            break;
                        default:
                            break;
                        }
                    }
                }
                if (types.value.equals("")) {
                    typetemp[0] = true;
                    typetemp[1] = true;
                    typetemp[2] = true;
                    typetemp[3] = true;
                }
                // 若输出所有省份数据 遍历数据,并按省份拼音排序写入文件
                if (provinces.value.equals("")) {
                    String[] provincesort = { "全国", "安徽", "北京", "重庆", "福建", "甘肃", "广东", "广西", "贵州", "海南", "河北", "河南", "黑龙江",
                        "湖北", "湖南", "江西", "吉林", "江苏", "辽宁", "内蒙古", "宁夏", "青海", "山西", "山东", "陕西", "上海", "四川", "天津", "西藏", "新疆",
                        "云南", "浙江" };
                    for (int i = 0; i < provincesort.length; ++i) {
                        String keytemp = provincesort[i];
                        int[] valuetemp = data.get(keytemp);
                        outline = keytemp;
                        if (typetemp[0]) {
                            outline = outline + " 感染患者" + valuetemp[0] + "人";
                        }
                        if (typetemp[1]) {
                            outline = outline + " 疑似患者" + valuetemp[1] + "人";
                        }
                        if (typetemp[2]) {
                            outline = outline + " 治愈" + valuetemp[2] + "人";
                        }
                        if (typetemp[3]) {
                            outline = outline + " 死亡" + valuetemp[3] + "人";
                        }
                        bw.write(outline);
                        bw.newLine();
                    }
                }
                // 若只输出-province参数值省份数据
                if (provinces.value.equals("valuelist")) {
                    for (String provincetemp : provinces.valueList) {
                        int[] valuetemp = data.get(provincetemp);
                        outline = provincetemp;
                        if (typetemp[0]) {
                            outline = outline + " 感染患者" + valuetemp[0] + "人";
                        }
                        if (typetemp[1]) {
                            outline = outline + " 疑似患者" + valuetemp[1] + "人";
                        }
                        if (typetemp[2]) {
                            outline = outline + " 治愈" + valuetemp[2] + "人";
                        }
                        if (typetemp[3]) {
                            outline = outline + " 死亡" + valuetemp[3] + "人";
                        }
                        bw.write(outline);
                        bw.newLine();
                    }
                }
                bw.write("// 该文档并非真实数据,仅供测试使用");
                bw.newLine();
                bw.flush();
                bw.close();
            } catch (Exception e) {
                System.out.println(e);
            }
        }
    

    六、单元测试

    1.ListCommand.checkInput(String[]):输入命令格式测试 ``` @Test public void checkInputOfListCommandTest() { // TODO Auto-generated method stub //正确案例 String[] args0= {"list", "-date", "2020-01-22", "-log", "D:/log/", "-out", "D:/output.txt","-type", "ip","-province","福建"}; Assert.assertEquals("checkInput:list -date 2020-01-22 -log D:/log/ -out D:/output.txt -type ip -province 福建",true,ListCommand.checkInput(args0) );
        //要求list开头
        String[] args1= {"List", "-date", "2020-01-22", "-log", "D:/log/", "-out", "D:/output.txt"};
        Assert.assertEquals("checkInput:List",false,ListCommand.checkInput(args1) );
    
        //不能缺少-log,-out同理
        String[] args2= {"list", "-date", "2020-01-22", "-out", "D:/output.txt"};
        Assert.assertEquals("checkInput:list -date 2020-01-22 -out D:/output.txt",false,ListCommand.checkInput(args2) );
    
        //参数不能写错-log -out -date -type -province
        String[] args3= {"list", "-d", "2020-01-22", "-log", "D:/log/", "-out", "D:/output.txt"};
        Assert.assertEquals("checkInput:-d 2020-01-22",false,ListCommand.checkInput(args3) );
    
        //同一参数不重复出现
        String[] args4= {"list", "-date", "2020-01-22", "-date", "2020-01-22", "-log", "D:/log/", "-out", "D:/output.txt"};
        Assert.assertEquals("checkInput:-date 2020-01-22 -date 2020-01-22",false,ListCommand.checkInput(args4) );
    
        System.out.println("checkInputOfListCommandTest OK");
    }
    
    <img src="https://img2018.cnblogs.com/blog/1934203/202002/1934203-20200220114736456-1754108294.png" width=300 />
    
    
    2.ListCommand.ListCommand(String[]):初始化赋值
    
    @Test
    public void newListCommandTest() {
        //正确案例
        String[] args0= {"list", "-date", "2020-01-22", "-log", "D:/log/", "-out", "D:/output.txt","-type", "ip","-province","福建","全国"};
        ListCommand aListCommand0=new ListCommand(args0);
        Assert.assertEquals("ListCommand.name:list","list",aListCommand0.name);
        Assert.assertEquals("ListCommand.argument[-log].name:-log","-log", aListCommand0.arguments[0].name);
        Assert.assertEquals("ListCommand.argument[-log].value:D:/log/","D:/log/", aListCommand0.arguments[0].value);
        Assert.assertEquals("ListCommand.argument[-type].value:-type ip","valuelist", aListCommand0.arguments[3].value);
        Assert.assertEquals("ListCommand.argument[-type].valueList:-type ip","ip", ((TypeArgument)aListCommand0.arguments[3]).valueList[0]);
        Assert.assertEquals("ListCommand.argument[-type].valueList:-type ip",1, ((TypeArgument)aListCommand0.arguments[3]).valueList.length);
        String[] strs0= {"福建","全国"};
        Assert.assertArrayEquals("ListCommand.argument[-province].valueList:-province 福建 全国",strs0, ((ProvinceArgument)aListCommand0.arguments[4]).valueList);
    
        //-log -out -date只能有一个参数 多出一个在value值前用*标识
        String[] args1= {"list", "-date", "2020-01-22", "-log", "D:/log/", "-out", "D:/output.txt", "D:/outputagain.txt","-type", "ip","-province","福建","全国"};
        ListCommand aListCommand1=new ListCommand(args1);
        Assert.assertEquals("ListCommand.argument[-out].name:-out D:/output.txt D:/outputagain.txt","*D:/output.txt", aListCommand1.arguments[1].value);
        
        System.out.println("newListCommandTest OK");
    }
    
    <img src="https://img2018.cnblogs.com/blog/1934203/202002/1934203-20200220115029616-827420930.png" width=300 />
    
    3.LogArgument.checkError():参数值检查
    
    @Test
    public void checkErrorOfLogArgumentTest() {
        //-log只能有一个参数值 -out -date同理 不再做测试
        String[] strs0= {"-log","D:/log/","D:/log/"};
        LogArgument aLogArgument0=new LogArgument(strs0);
        Assert.assertEquals("LogCommand.checkError:-log D:/log/ D:/log/",false,aLogArgument0.checkError());
        
        //-log的参数值必须是一个目录的路径
        String[] strs1= {"-log","D:/log/"};
        LogArgument aLogArgument1=new LogArgument(strs1);
        Assert.assertEquals("LogCommand.checkError:-log D:/log/",true,aLogArgument1.checkError());
        String[] strs2= {"-log","D:/alog/"};
        LogArgument aLogArgument2=new LogArgument(strs2);
        Assert.assertEquals("LogCommand.checkError:-log D:/alog/",false,aLogArgument2.checkError());
    
        System.out.println("checkErrorOfLogArgumentTest OK");
    }
    
    <img src="https://img2018.cnblogs.com/blog/1934203/202002/1934203-20200220115249165-1298207791.png" width=300 />
    
    4.OutArgument.checkError():参数值检查
    
    @Test
    public void checkErrorOfOutArgumentTest() {
        // -out参数值若后缀不为.txt 则修改为默认
        String[] strs0= {"-out","D:/output.tx"};
        OutArgument aOutArgument0 =new OutArgument(strs0);
        aOutArgument0.checkError();
        Assert.assertEquals("OutCommand.checkError:-out D:/output.tx","D:/output.txt",aOutArgument0.value);
    
        //-out参数值若没有后缀 则修改为默认
        String[] strs1= {"-out","D:/output"};
        OutArgument aOutArgument1 =new OutArgument(strs1);
        aOutArgument1.checkError();
        Assert.assertEquals("OutCommand.checkError:-out D:/output","D:/output.txt",aOutArgument1.value);
        
        System.out.println("checkErrorOfOutArgumentTest OK");
    }
    
    <img src="https://img2018.cnblogs.com/blog/1934203/202002/1934203-20200220115821050-378208813.png" width=300 />
    
    5.DateArgument.checkError():参数值检查
    

    @Test
    public void checkErrorOfDateArgumentTest() {
    //-date 满足平年闰年的YYYY-MM-DD格式 否则修改为默认最新日期
    String[] strs0= {"-date","2020-1-22"};
    DateArgument aDateArgument0 =new DateArgument(strs0);
    aDateArgument0.checkError();
    Assert.assertEquals("DateCommand.checkError:-date 2020-1-22","lastdate",aDateArgument0.value);

        String[] strs1= {"-date","2021-02-29"};
        DateArgument aDateArgument1 =new DateArgument(strs1);
        aDateArgument1.checkError();
        Assert.assertEquals("DateCommand.checkError:-date 2021-2-29","lastdate",aDateArgument1.value);
        
        System.out.println("checkErrorOfDateArgumentTest OK");
    }
    
    <img src="https://img2018.cnblogs.com/blog/1934203/202002/1934203-20200220121435638-607754040.png" width=300 />
    
    6.TypeArgument.checkError():参数值检查
    
    @Test
    public void checkErrorOfTypeArgumentTest() {
        //-type参数值只能为ip,sp,cure,dead 若不是就忽略该错误输入
        String[] strs0= {"-type","ip","dye"};
        TypeArgument aTypeArgument0=new TypeArgument(strs0);
        aTypeArgument0.checkError();
        String[] strs00= {"ip"};
        Assert.assertArrayEquals("TypeCommand.checkError:-type ip dye",strs00,aTypeArgument0.valueList);
        
        //-type参数值若全部输入错误 则视为参数缺省
        String[] strs1= {"-type","p","dye"};
        TypeArgument aTypeArgument1=new TypeArgument(strs1);
        aTypeArgument1.checkError();
        String[] strs11= {"ip","sp","cure","dead"};
        Assert.assertArrayEquals("TypeCommand.checkError:-type p dye",strs11,aTypeArgument1.valueList);
        
        //-type 参数值不能重复 重复则删去 同-province
        String[] strs2= {"-type","ip","ip"};
        TypeArgument aTypeArgument2=new TypeArgument(strs2);
        aTypeArgument2.checkError();
        String[] strs22= {"ip"};
        Assert.assertArrayEquals("TypeCommand.checkError:-type ip ip",strs22,aTypeArgument2.valueList);
        
        System.out.println("checkErrorOfTypeArgumentTest OK");
    }
    
    <img src="https://img2018.cnblogs.com/blog/1934203/202002/1934203-20200220122839383-912734898.png" width=300 />
    
    7.ProvinceArgument.checkError(Statistic):参数值检查
    
    @Test
    public void checkErrorOfProvinceArgumentTest() {
        //-province参数值省份必须存在,若不存在则默认列出所有
        Statistic aStatistic=new Statistic();
        String[] strs0= {"-province","福建","厦门"};
        ProvinceArgument aProvinceArgument0=new ProvinceArgument(strs0);
        aProvinceArgument0.checkError(aStatistic);
        Assert.assertEquals("ProvinceCommand.checkError:-province 福建 厦门","",aProvinceArgument0.value);
        
        System.out.println("checkErrorOfProvinceArgumentTest OK");
    }
    
    <img src="https://img2018.cnblogs.com/blog/1934203/202002/1934203-20200220123943781-2008520383.png" width=300 />
    
    8.LogFiles.LogFiles(String):初始化并对文件进行管理
    
    @Test
    public void newLogFilesTest() {
        LogFiles aLogFiles0=new LogFiles("D:/log/");
        //TreeSet存放文件并按日期排序
        String[] strs0= {"2019-12-27","2020-01-22","2020-01-23","2020-01-25","2020-01-27","2020-02-01"};
        int i=0;
        for(File f:aLogFiles0.files) {
            Assert.assertEquals("LogFiles.new:sort",strs0[i]+".log.txt", f.getName());
            ++i;
        }
        
        //lastDate为日志文件中最晚日期
        Assert.assertEquals("LogFiles.new:sort","2020-02-01", aLogFiles0.lastDate);
        
        System.out.println("newLogFilesTest OK");
    }
    
    <img src="https://img2018.cnblogs.com/blog/1934203/202002/1934203-20200220131324544-309790747.png" width=150 />
    <img src="https://img2018.cnblogs.com/blog/1934203/202002/1934203-20200220131421147-1710015492.png" width=300 />
    
    9.LogFiles.dateCompare(String,String):比较两个YYYY-MM-DD日期字符串
    
    @Test
    public void dataCompareOfLogFilesTest(){
        //比较两个YYYY-MM-DD日期字符串 若date0大于等于date1 则返回true
        String str0="2020-01-01";
        String str1="2020-03-01";
        String str2="2019-03-01";
        String str3="2020-01-22";
        Assert.assertEquals("LogFiles.dateCompare:(2020-01-01,2020-03-01)",false, LogFiles.dateCompare(str0, str1));
        Assert.assertEquals("LogFiles.dateCompare:(2020-01-01,2019-03-01)",true, LogFiles.dateCompare(str0, str2));
        Assert.assertEquals("LogFiles.dateCompare:(2020-01-01,2020-01-22)",false, LogFiles.dateCompare(str0, str3));
    
        System.out.println("dataCompareOfLogFilesTest OK");
    }
    
    <img src="https://img2018.cnblogs.com/blog/1934203/202002/1934203-20200220133624577-823092734.png" width=300 />
    
    9.LogFiles.statisLine(String,Statistic):处理日志文件中的一行,更改数据
    
    @Test
    public void statisLineOfLogFilesTest() {
        Statistic aStatistic=new Statistic();
        //处理日志文件中的一行
        String str0="福建 新增 疑似患者 3人";
        LogFiles.statisLine(str0, aStatistic);
        Assert.assertEquals("LogFiles.statisLine:福建 新增 疑似患者 3人",3, (aStatistic.data.get("福建"))[1]);
    
        String str1="福建 新增 感染患者 2人";
        LogFiles.statisLine(str1, aStatistic);
        Assert.assertEquals("LogFiles.statisLine:福建 新增 感染患者 2人",2, (aStatistic.data.get("福建"))[0]);
        
        String str2="福建 治愈 1人";
        LogFiles.statisLine(str2, aStatistic);
        Assert.assertEquals("LogFiles.statisLine:福建 治愈 1人",1, (aStatistic.data.get("福建"))[0]);
        Assert.assertEquals("LogFiles.statisLine:福建 治愈 1人",1, (aStatistic.data.get("福建"))[2]);
        
        String str3="福建 疑似患者 流入 湖南 2人";
        LogFiles.statisLine(str3, aStatistic);
        Assert.assertEquals("LogFiles.statisLine:福建 疑似患者 流入 湖南 2人",1, (aStatistic.data.get("福建"))[1]);
        Assert.assertEquals("LogFiles.statisLine:福建 疑似患者 流入 湖南 2人",2, (aStatistic.data.get("湖南"))[1]);
        
        System.out.println("statisLineOfLogFilesTest OK");
    }
    
    <img src="https://img2018.cnblogs.com/blog/1934203/202002/1934203-20200220142740161-2036516319.png" width=300 />
    
    10.LogFiles.statisFile(File,Statistic):处理一个日志文件,更改数据
    
    @Test
    public void statisFileOfLogFiles() {
        Statistic aStatistic=new Statistic();
        File file=new File("D:/log/2020-01-22.log.txt");
        LogFiles.statisFile(file, aStatistic);
        
        Assert.assertEquals("LogFiles.statisFile:D:/log/2020-01-22.log.txt",5, (aStatistic.data.get("福建"))[0]);
        Assert.assertEquals("LogFiles.statisFile:D:/log/2020-01-22.log.txt",7, (aStatistic.data.get("福建"))[1]);
        Assert.assertEquals("LogFiles.statisFile:D:/log/2020-01-22.log.txt",0, (aStatistic.data.get("福建"))[2]);
        Assert.assertEquals("LogFiles.statisFile:D:/log/2020-01-22.log.txt",0, (aStatistic.data.get("福建"))[3]);
        Assert.assertEquals("LogFiles.statisFile:D:/log/2020-01-22.log.txt",10, (aStatistic.data.get("湖北"))[0]);
        Assert.assertEquals("LogFiles.statisFile:D:/log/2020-01-22.log.txt",15, (aStatistic.data.get("湖北"))[1]);
        Assert.assertEquals("LogFiles.statisFile:D:/log/2020-01-22.log.txt",2, (aStatistic.data.get("湖北"))[2]);
        Assert.assertEquals("LogFiles.statisFile:D:/log/2020-01-22.log.txt",1, (aStatistic.data.get("湖北"))[3]);
        
        System.out.println("statisFileOfLogFiles OK");
    }
    
    <img src="https://img2018.cnblogs.com/blog/1934203/202002/1934203-20200220143710822-142527829.png" width=500 />
    <img src="https://img2018.cnblogs.com/blog/1934203/202002/1934203-20200220143737729-30352551.png" width=300 />
    
    11.LogFiles.readFiles(String,Statistic): 按日期处理一个日志目录下的文件
    
    @Test
    public void readFilesOfLogFilesTest() {
        //根据-date处理一个日志目录下的文件
        LogFiles aLogFiles=new LogFiles("D:/log/");
        
        //默认最新日期 处理全部日志
        Statistic aStatistic0=new Statistic();
        aLogFiles.readFiles("lastdate", aStatistic0);
        Assert.assertEquals("LogFiles.readFiles:lastdate",22, (aStatistic0.data.get("福建"))[0]);
    
        //处理到传入日期为止
        Statistic aStatistic1=new Statistic();
        aLogFiles.readFiles("2020-01-25", aStatistic1);
        Assert.assertEquals("LogFiles.readFiles:2020-01-25",9, (aStatistic1.data.get("福建"))[0]);
    
        System.out.println("readFilesOfLogFilesTest OK");
    }
    
    <img src="https://img2018.cnblogs.com/blog/1934203/202002/1934203-20200220145343826-1305032759.png" width=150 />
    <img src="https://img2018.cnblogs.com/blog/1934203/202002/1934203-20200220145427191-1839263252.png" width=300 />
    
    
    <h3 id="7">七、单元测试性能及优化</h3>
    下面是上述单元测试的覆盖率表格,覆盖率达74.1%
    
    <img src="https://img2018.cnblogs.com/blog/1934203/202002/1934203-20200220171453411-1041799833.png" width=800 />
    
    可以非常明显地发现原单元测试的覆盖率短板在于对Statistic类的测试,再次展开
    
    <img src="https://img2018.cnblogs.com/blog/1934203/202002/1934203-20200220171837705-187235220.png" width=700 />
    
    定位到原单元测试遗漏的函数Statistic.outPutFile(String, TypeArgument, ProvinceArgument)
    针对Statistic.outPutFile(String, TypeArgument, ProvinceArgument)编写单元测试
    
    @Test
    public void outPutFileOfStatisticTest() {
        Statistic aStatistic=new Statistic();
        
        //若-type是缺省的值,指定-province
        String path0="D:/outPutTest0.txt";
        TypeArgument aTypeArgument0=new TypeArgument("-type");
        String[] pro0= {"-province","福建"};
        ProvinceArgument aProvinceArgument0=new ProvinceArgument(pro0);
        aStatistic.outPutFile(path0, aTypeArgument0, aProvinceArgument0);
    
        //若-province是缺省的值,指定-type
        String path1="D:/outPutTest1.txt";
        String[] typ1= {"-type","ip","sp"};
        TypeArgument aTypeArgument1=new TypeArgument(typ1);
        ProvinceArgument aProvinceArgument1=new ProvinceArgument("-province");
        aStatistic.outPutFile(path1, aTypeArgument1, aProvinceArgument1);
    
        System.out.println("outPutFileOfStatisticTest OK");
        System.out.println("please check outPutTest.txt");
    }
    
    测试结果如下
    
    <img src="https://img2018.cnblogs.com/blog/1934203/202002/1934203-20200220174527153-736183809.png" width=300 />
    
    <img src="https://img2018.cnblogs.com/blog/1934203/202002/1934203-20200220174554810-30162781.png" width=400 />
    
    <img src="https://img2018.cnblogs.com/blog/1934203/202002/1934203-20200220174602839-714201414.png" width=300 />
    
    经过改进后,覆盖率达到了90.5%
    
    
    <h3 id="8">八、代码规范</h3>
    [GaogaoHub仓库]<https://github.com/GaogaoHub>
    [博客 Gao_JAVA编程规约]<https://www.cnblogs.com/GaogaoBlog/p/12309393.html>
    
    <h3 id="9">九、总结和收获</h3>
    刚收到这份作业的时候,被五花八门的各种要求晃得眼花,拖延症发作,下意识地把它放放。奈何寒假真的太过清闲,放下没半天,又老实打开作业要求。第一个观感是这次疫情统计程序的作业与以往的作业很不一样,除了前置准备工作外,第一次收到一份较为完整的需求文档,按需求设计编程,并且不断使用commit记录签入。因此也是第一次完成一个程序的具体设计,再进行编程。
    PS:作业周期很长,悠悠哉哉地写好幸福www
    这次作业最大的收获应该是通过阅读邹欣老师的博客使用PSP表格来完成一项软件开发,过程中最出乎我意料的是,比起我预计的时间花费,设计的部分实际花费更多时间,而编码部分的时间比我预期的要少得多。过去编程时在编码花费大量时间,更多是因为编码前只有一个脑海中的模糊的体系,不完备不准确,时常推翻重写。
    当然这次也存在这种情况:设计的不合理之处在编码时才发现。但都只是局部的修改,无伤大雅。比如在编码过程中发现设计的不合理之处,比如应用一个类来封装数据,而原来只在main中设计了一个map变量存放,因此再次修改了类图。又比如在初始设计时,由于对Java集合了解不够全面,选择用数组来存放目录下的日志文件,编码时涉及到文件排序的具体实现,就改为用TreeSet来存放。
    
    <h3 id="10">十、仓库们们们们们</h3>
    
    1.[alibaba-java-style-guide阿里巴巴JAVA开发手册](https://github.com/chjw8016/alibaba-java-style-guide)
    仓库内有主流的完善的JAVA编程规范供参考,包括编程规约、异常日志、MYSQL规约、工程规约、安全规约,这次编程规范的学习和编写主要来自↑仓库的编程规约。
    
    2.[cz-cli commitizen命令行实用工具](https://github.com/commitizen/cz-cli)
    使用commitizen进行commit,系统会提示您在提交时填写所有必需的提交字段,自动生成规范的commit语句。
    
    3.[JacaScriop前端特效存档](https://github.com/yangxi0126/javaScript)
    一些JavaScript的前端特效范例,包括范例的各个版本,有参考意义。
    
    4.[HTML5学习、总结、实践](https://github.com/NalvyBoo/HTML5)
    记录了NalvyBoo的学习路线,主要是学习过程中的实践程序,进行了详解的归档。
    
    5.[JavaScript30个挑战](https://github.com/wesbos/JavaScript30)
    如题哇。
  • 相关阅读:
    CF13D. Triangles
    CF1142C. U2
    2020 省选模拟测试 Round #8 solution (20/02/07)
    2020 省选模拟测试 Round #7 solution (20/02/06)
    2020 省选模拟测试 Round #6 solution (20/02/05)
    2020 省选模拟测试 Round #5 solution (20/02/04)
    2020 省选模拟测试 Round #4 solution (20/02/03)
    CF1291D. Irreducible Anagrams
    CF1264E. Beautiful League
    bzoj2002 弹飞绵羊
  • 原文地址:https://www.cnblogs.com/GaogaoBlog/p/12307853.html
Copyright © 2020-2023  润新知