软工实践寒假作业(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的相关知识,在刚开始看到题目的时候觉得可能挺难的,后来通过挺长时间对题目的理解,再加上一些同学的帮助,还有众多的课外阅读之后,发现其实是可以做出来的,虽然用的方法比较粗笨,但自己动手实践起来果然是不一样的效果。

构建之法的学习使得我不断地细分函数,从而提高了代码的利用率,也使得函数看着不那么的冗杂。今后也会继续努力将实践与理论相结合,提升自己。

第一次作业中技术路线图相关仓库

  1. interface-testing

HTTP接口测试可以把后台逻辑单独进行测试,便于模块化测试和问题定位;HTTP接口自动化测试由于执行稳定、维护成本相对较低,是自动化测试一个很好的切入点;也可以跟UI自动化测试结合,提高回归测试自动化覆盖率。

从接口测试用例设计到测试实施,从Postman到TestNG+HttpClient,看到整个项目HTTP接口测试的全过程。

1.1. 深入理解HTTP接口和HTTP接口测试的概念;
1.2. 掌握HTTP接口用例分析与设计方法;
1.3. 掌握用Postman执行实际项目的HTTP接口测试;
1.4. 掌握用TestNG+HttpClient编写接口测试代码,做到全自动化测试
  1. foundation-software-tesing

    一门关于软件测试与质量的入门课程,面向软件或计算机专业的学生,或对软件测试有兴趣的学员,围绕软件测试与质量的基本概念、核心方法、管理与应用、软件质量与度量等内容展开讨论。

  2. 测试学习笔记

    包含系统测试模块,UFT与Selenium自动化测试,WEB测试模块,LR性能测试以及项目实战,具有重要意义。

  3. software-testing

    东南大学《软件测试及应用》,其中包含了软件测试基础实验教程,适合初学者。

  4. 测试资料和脚本

    在学习使用peach进行模糊测试时,搜集到的一些不错的资料,以及配套的一些软件或脚本。

posted @ 2020-02-18 21:35  XP二二不  阅读(357)  评论(0编辑  收藏  举报