软工实践寒假作业(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 |
解题思路
通过构建一个二维数组存放各个省份各个类型的病人数目,结合对正则表达式的应用处理数据存放在对应的位置。

关键函数流程图
%E5%87%BD%E6%95%B0.png)
代码说明
-
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)) {
ArrayListfilenames=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 {
ListfileList = 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进行模糊测试时,搜集到的一些不错的资料,以及配套的一些软件或脚本。

软工实践寒假作业(2/2)学习使用GitHub,编写疫情统计程序,制定代码规范并编写PSP表格,完成单元测试
浙公网安备 33010602011771号