软工实践寒假作业(2/2)
这个作业属于哪个课程 | 2020春S班(福州大学) |
---|---|
这个作业要求在哪里 | 软工实践寒假作业(2/2) |
这个作业的目标 | 学习使用GitHub,编写疫情统计程序,制定代码规范并编写PSP表格,完成单元测试 |
作业正文 | 软工实践寒假作业2/2 |
其他参考文献 | 百度百科,博客园,CSDN,知乎,菜鸟教程 |
GitHub仓库地址
https://github.com/XP228-x/InfectStatistic-main
PSP表格
PSP2.1 | Personal Software Process Stages | 预估耗时(分钟) | 实际耗时(分钟) |
---|---|---|---|
Planning | 计划 | 100 | 145 |
Estimate | 估计这个任务需要多少时间 | 20 | 30 |
Development | 开发 | 1230 | 1510 |
Analysis | 需求分析 (包括学习新技术) | 90 | 105 |
Design Spec | 生成设计文档 | 75 | 90 |
Design Review | 设计复审 | 60 | 70 |
Coding Standard | 代码规范 (为目前的开发制定合适的规范) | 45 | 55 |
Design | 具体设计 | 150 | 180 |
Coding | 具体编码 | 540 | 655 |
Code Review | 代码复审 | 105 | 125 |
Test | 测试(自我测试,修改代码,提交修改) | 195 | 230 |
Reporting | 报告 | 135 | 145 |
Test Repor | 测试报告 | 45 | 55 |
Size Measurement | 计算工作量 | 30 | 35 |
Postmortem & Process Improvement Plan | 事后总结, 并提出过程改进计划 | 45 | 55 |
合计 | 1500 | 1820 |
解题思路
通过构建一个二维数组存放各个省份各个类型的病人数目,结合对正则表达式的应用处理数据存放在对应的位置。
关键函数流程图
代码说明
-
init()程序初始化,判断命令参数的类型。
public void init(String[] args) throws Exception { char a = '-'; String dic = null; String path = null ; String date=null; boolean status=false; String[] type = new String[4]; String[] provinces = new String[31]; for (int i = 0; i < args.length; i++) { if ("-log".equals(args[i])) { dic = args[i + 1]; } else if ("-out".equals(args[i])) { path = args[i + 1]; } else if ("-date".equals(args[i])) { date = args[i + 1]; status=true; } else if ("-type".equals(args[i])) { flag1 = true; int k = 0; for (int j = i + 1; j < args.length && args[j].toCharArray()[0] != a; j++) { type[k++] = args[j]; } } else if ("-province".equals(args[i])) { flag2 = true; int k = 0; for (int j = i + 1; j < args.length && args[j].toCharArray()[0] != a; j++) { provinces[k++] = args[j]; } } } if (isExistPath(path)) { ArrayList<String> filenames=new ArrayList<>(); if(!status){ sortFilename(dic,filenames); date=filenames.get(filenames.size()-2); } provinces = sortProvinces(provinces); type = deleteArrayNull(type); if (isValidDate(date, dic) && isValidProvince(provinces) || !flag2 && isValidDate(date, dic)) { outputFile(path, dic, date); dealFlag(type, provinces); System.out.println("// 该文档并非真实数据,仅供测试使用\n"); } else { isValidDate(date, dic); if (!isValidDate(date, dic)) { System.out.println("日期格式不合法!"); } else if (!isValidProvince(provinces)) { System.out.println("省份错误!"); } } } }
-
outputFile()函数处理日志目录下的目录文件
public void outputFile(String outfile, String dictionary, String date) throws IOException { List<File> fileList = getFiles(dictionary); File fout = new File(outfile); FileWriter fw = new FileWriter(fout); for (File f : fileList) { String filename; filename = f.getName().substring(0, f.getName().indexOf(".")); if (date.compareTo(filename) >= 0) { FileReader fr = new FileReader(f); BufferedReader br = new BufferedReader(fr); String line = br.readLine(); while (line != null) { dealLine(line); line = br.readLine(); } fr.close(); } } String lines = getAllProvince(); fw.append(lines).append("\n"); for (int i = 0; i < number.length; i++) { if (discovery[i]) { String theline = province[i] + " " + type2[0] + number[i][0] + person + " " + type2[1] + number[i][1] + person + " " + type2[2] + number[i][2] + person + " " + type2[3] + number[i][3] + person; fw.append(theline).append("\n"); } } fw.append("// 该文档并非真实数据,仅供测试使用\n"); fw.close(); }
-
dealLine()函数处理日志文件中的每一行数据并存到相应数组。
private void dealLine(String line) { int num; for (int i = 0; i < K; i++) { int flag = 0; int flag1 = 0; int flag2 = 0; Pattern r = Pattern.compile(pattern[i]); Matcher m = r.matcher(line); if (m.find()) { num = i; for (int i1 = 0; i1 < province.length; i1++) { if (province[i1].equals(m.group(1))) { flag = i1; discovery[i1] = true; } boolean status = (num == 2 || num == 3) && province[i1].equals(m.group(2)); if (status) { discovery[i1] = true; flag1 = i1; } boolean status1 = (num == 2 || num == 3) && province[i1].equals(m.group(1)); if (status1) { discovery[i1] = true; flag2 = i1; } }if (num == 2) { //流入流出 number[flag1][0] += Integer.parseInt(m.group(3)); number[flag2][0] -= Integer.parseInt(m.group(3)); } else if (num == 3) { number[flag1][1] += Integer.parseInt(m.group(3)); number[flag2][1] -= Integer.parseInt(m.group(3)); } else if (num == 7) { //排除类型 number[flag][1] -= Integer.parseInt(m.group(2)); } else if (num == 5) { //治愈和死亡类型 number[flag][0] -= Integer.parseInt(m.group(2)); number[flag][2] += Integer.parseInt(m.group(2)); } else if (num == 4) { number[flag][0] -= Integer.parseInt(m.group(2)); number[flag][3] += Integer.parseInt(m.group(2)); } else if (num == 6) { //疑似->确认 number[flag][0] += Integer.parseInt(m.group(2)); number[flag][1] -= Integer.parseInt(m.group(2)); } else { number[flag][num] += Integer.parseInt(m.group(2)); } } } }
-
dealFlag()函数判断命令行是哪种模式并选择相应的处理函数。(Flag1和Flag2分别对应-type和-province参数是否出现)
public void dealFlag( String[] type, String[] provinces) { if (!flag1&&flag2) { dealProvince( provinces); } else if (flag1 && flag2) { dealTypeAndProvince( type, provinces); } if (flag1 && !flag2) { dealType(type); } else if(!flag2){ dealNormal(); }
}
-
dealTypeAndProvince()函数处理(取出二维数组中对应的数据即可)
private void dealTypeAndProvince(String[] type, String[] provinces) { provinces=deleteArrayNull(provinces); for (String s : provinces) { if ("全国".equals(s) && isValidType(type)) { System.out.println(getAllProvinceType(type)); } for (int j = 0; j < province.length; j++) { if (s.equals(province[j])) { System.out.print(province[j] + " "); for (String t : type) { if (t != null) { switch (t) { case "ip": System.out.print(type2[0] + number[j][0] + person + " "); break; case "sp": System.out.print(type2[1] + number[j][1] + person + " "); break; case "cure": System.out.print(type2[2] + number[j][2] + person + " "); break; case "dead": System.out.print(type2[3] + number[j][3] + person + " "); break; default: System.out.print("无该患者类型,请重新选择!"); break; } } } System.out.print("\n"); } } } }
单元测试截图和描述
测试结果
测试结果符合标准
性能优化截图和描述
代码覆盖率
测试样例未考虑到错误参数情况,于是优化了测试内容。
优化过后
性能截图
代码规范链接
https://github.com/XP228-x/InfectStatistic-main/blob/master/221701203/codestyle.md
心路历程与收获
在这次的java编程中,我重新复习了java的相关知识,在刚开始看到题目的时候觉得可能挺难的,后来通过挺长时间对题目的理解,再加上一些同学的帮助,还有众多的课外阅读之后,发现其实是可以做出来的,虽然用的方法比较粗笨,但自己动手实践起来果然是不一样的效果。
构建之法的学习使得我不断地细分函数,从而提高了代码的利用率,也使得函数看着不那么的冗杂。今后也会继续努力将实践与理论相结合,提升自己。
第一次作业中技术路线图相关仓库
HTTP接口测试可以把后台逻辑单独进行测试,便于模块化测试和问题定位;HTTP接口自动化测试由于执行稳定、维护成本相对较低,是自动化测试一个很好的切入点;也可以跟UI自动化测试结合,提高回归测试自动化覆盖率。
从接口测试用例设计到测试实施,从Postman到TestNG+HttpClient,看到整个项目HTTP接口测试的全过程。
1.1. 深入理解HTTP接口和HTTP接口测试的概念;
1.2. 掌握HTTP接口用例分析与设计方法;
1.3. 掌握用Postman执行实际项目的HTTP接口测试;
1.4. 掌握用TestNG+HttpClient编写接口测试代码,做到全自动化测试
-
一门关于软件测试与质量的入门课程,面向软件或计算机专业的学生,或对软件测试有兴趣的学员,围绕软件测试与质量的基本概念、核心方法、管理与应用、软件质量与度量等内容展开讨论。
-
包含系统测试模块,UFT与Selenium自动化测试,WEB测试模块,LR性能测试以及项目实战,具有重要意义。
-
东南大学《软件测试及应用》,其中包含了软件测试基础实验教程,适合初学者。
-
在学习使用peach进行模糊测试时,搜集到的一些不错的资料,以及配套的一些软件或脚本。