实验五 单元测试

一、实验目的

1)掌握单元测试的方法

2) 学习XUnit测试原理及框架;

3)掌握使用测试框架进行单元测试的方法和过程。

二、实验内容与要求

1、了解单元测试的原理与框架

  1.1 单元测试原理

  单元测试(unit testing),是指对软件中的最小可测试单元进行检查和验证。对于单元测试中单元的含义,一般来说,要根据实际情况去判定其具体含义,如C语言中单元指一个函数,Java里单元指一个类,图形化的软件中可以指一个窗口或一个菜单等。总的来说,单元就是人为规定的最小的被测功能模块。单元测试是在软件开发过程中要进行的最低级别的测试活动,软件的独立单元将在与程序的其他部分相隔离的情况下进行测试。单元测试是由程序员自己来完成,最终受益的也是程序员自己。可以这么说,程序员有责任编写功能代码,同时也就有责任为自己的代码编写单元测试。执行单元测试,就是为了证明这段代码的行为和我们期望的一致。

单元测试的内容包括

  模块接口测试、局部数据结构测试、路径测试、错误处理测试、边界测试

  1.2 测试框架

 xUnit是各种代码驱动测试框架的统称,这些框架可以测试 软件的不同内容(单元),比如函数和类。xUnit框架的主要优点是,它提供了一个自动化测试的解决方案。可以避免多次编写重复的测试代码。

底层是xUnit的framwork,xUnit的类库,提供了对外的功能方法、工具类、api等

TestCase(具体的测试用例)去使用framwork

TestCase执行后会有TestResult

使用TestSuite控制TestCase的组合

TestRunner执行器,负责执行case

TestListener过程监听,监听case成功失败以及数据结果,输出到结果报告

1.3   面向特定语言的,基于xUnit框架的自动化测试框架

    Junit  : 主要测试用Java语言编写的代码

    CPPunit:主要测试用C++语言编写的代码

   unittest , PyUnit:主要测试用python语言编写的代码

   MiniUnit:   主要用于测试C语言编写的代

JUnit是一个开发源代码的Java测试框架,用于编写和运行可重复的测试。他是用于单元测试框架体系xUnit的一个实例(用于java语言)

Eclipse 集成了 JUnit,可以非常方便地编写 Test Case。Eclipse 自带了一个 JUnit 插件,不用安装就可以在项目中测试相关的类,并且可以调试测试用例和被测类。下面以实例说明,如何建立一个基于 JUnit4 的测试项目,对一个类当中的多个方法进行单元测试。

因为此次我们小组的测试代码设计是 java ,所以我们采用Eclipse自带的 JUnit 进行案例的测试。

2、结对编程的小组采用测试框架 对自己“结对编程”实验的程序模块(类)进行单元测试

  1)源码 

  1 package sizeyusuan;
  2 
  3 import java.util.*;
  4 import java.io.BufferedReader;
  5 import java.io.BufferedWriter;
  6 import java.io.File;
  7 import java.io.FileOutputStream;
  8 import java.io.FileReader;
  9 import java.io.FileWriter;
 10 import java.io.IOException;
 11 import java.io.OutputStreamWriter;
 12 import java.io.PrintWriter;
 13 import java.io.RandomAccessFile; 
 14 public class xiaoxuesheng {
 15     private static Random random = new Random();
 16     public static int range;
 17     public static String reductionofFraction(int a, int b) {// 分数约分,用于计算结果
 18         int y = 1;
 19         for (int i = a; i >= 1; i--) {
 20             if (a % i == 0 && b % i == 0) {
 21                 y = i;
 22                 break;
 23             }
 24         }
 25         int z = a / y;// 分子
 26         int m = b / y;// 分母
 27         if (z == 0) {
 28             return "0";
 29         }
 30         if(m==1) return z+"";
 31         else  return biaodashi(z,m);
 32         
 33     }
 34     public static String biaodashi(int a,int b) {//判断假分数,并化假分数为带分数
 35         if(a>=b) {
 36             int c;
 37             c=a/b;
 38             int d;
 39             d=a%b; 
 40             {if(d==0) {return c+"";}
 41             return c+"'"+d+"/"+b;}
 42         }return a+"/"+b;
 43     }
 44     
 45 public static void main(String[] args){
 46      Scanner sc= new Scanner(System.in);
 47      System.out.println("请输入产生几以内的数字:");
 48      range=sc.nextInt();
 49      System.out.println("请输入产生多少个运算表达式:");
 50      int num=sc.nextInt();
 51      int rightcount[]=new int[num+2];
 52      int wrongcount[]=new int[num+2];
 53      int right1=0;
 54     int wrong1=0;
 55     String[] results=new String[num];int i;
 56      for( i=0;i<num;i++){ 
 57      
 58         String expArr[]=new String[2];//定义生成的题目
 59         int a= (int) (random.nextInt(range));//分子
 60         int b= (int) (random.nextInt(range));//分母
 61         int c= (int) (random.nextInt(range));//另一个分子
 62         int d= (int) (random.nextInt(range));//另一个分母
 63         int fuhao;//运算符
 64         fuhao= (int) (random.nextInt(4));
 65         if(b!=0&&d!=0) {//分母均不为0时生成带有分数的计算题,同时计算结果
 66         if(fuhao==0) {
 67             int fenzi=a*d+b*c;
 68             int fenmu=b*d;
 69             expArr[0]=biaodashi(a,b)+'+'+biaodashi(c,d)+'=';
 70             System.out.println(expArr[0]);
 71             results[i]=reductionofFraction(fenzi, fenmu);
 72         
 73         }
 74         if(fuhao==1&&a*d-b*c>=0) {
 75             int fenzi=a*d-b*c;
 76             int fenmu=b*d;
 77             expArr[0]=biaodashi(a,b)+'-'+biaodashi(c,d)+'=';
 78             System.out.println(expArr[0]);
 79             results[i]=reductionofFraction(fenzi, fenmu);
 80             
 81         }
 82         if(fuhao==1&&a*d-b*c<0) {
 83             int fenzi=b*c-a*d;
 84             int fenmu=b*d;
 85             expArr[0]=biaodashi(a,b)+'-'+biaodashi(c,d)+'=';
 86             System.out.println(expArr[0]);
 87             results[i]=reductionofFraction(fenzi, fenmu);
 88             
 89         }
 90         if(fuhao==2) {
 91             int fenzi=a*c;
 92             int fenmu=b*d;
 93             expArr[0]=biaodashi(a,b)+'×'+biaodashi(c,d)+'=';
 94             System.out.println(expArr[0]);
 95             results[i]=reductionofFraction(fenzi, fenmu);
 96             
 97         }
 98         if(fuhao==3&&c!=0) {
 99             int fenzi=a*d;
100             int fenmu=b*c;
101             expArr[0]=biaodashi(a,b)+'÷'+biaodashi(c,d)+'=';
102             System.out.println(expArr[0]);
103             results[i]=reductionofFraction(fenzi, fenmu);
104             
105         }
106         if(fuhao==3&&c==0) {
107             break;
108             /*c=1;
109             int fenzi=a*d;
110             int fenmu=b*c;
111             expArr[0]=biaodashi(a,b)+'÷'+biaodashi(c,d)+'=';
112             System.out.println(expArr[0]);
113             results[i]=reductionofFraction(fenzi, fenmu);*/
114             
115         }
116         
117         }
118         else {//分母至少一个为0时生成只含有整式的运算式,同时计算结果
119             b=1; d=1;
120             if(fuhao==0) {
121             int fenzi=a*d+b*c;
122             int fenmu=b*d;
123             expArr[0]=a+"+"+c+"=";
124             System.out.println(expArr[0]);
125             results[i]=reductionofFraction(fenzi, fenmu);
126             
127         }
128         if(fuhao==1&&a*d-b*c>=0) {
129             int fenzi=a*d-b*c;
130             int fenmu=b*d;
131             expArr[0]=a+"-"+c+"=";
132             System.out.println(expArr[0]);
133             results[i]=reductionofFraction(fenzi, fenmu);
134             
135         }
136         if(fuhao==1&&a*d-b*c<0) {
137             int fenzi=b*c-a*d;
138             int fenmu=b*d;
139             expArr[0]=c+"-"+a+"=";
140             System.out.println(expArr[0]);
141             results[i]=reductionofFraction(fenzi, fenmu);
142             
143         }
144         if(fuhao==2) {
145             int fenzi=a*c;
146             int fenmu=b*d;
147             expArr[0]=c+"×"+a+"=";
148             System.out.println(expArr[0]);
149             results[i]=reductionofFraction(fenzi, fenmu);
150             
151         }
152         if(fuhao==3&&c!=0) {
153             int fenzi=a*d;
154             int fenmu=b*c;
155             expArr[0]=a+"÷"+c+"=";
156             System.out.println(expArr[0]);
157             results[i]=reductionofFraction(fenzi, fenmu);
158             
159         }
160         if(fuhao==3&&c==0) {
161             break;
162             /*c=1;
163             int fenzi=a*d;
164             int fenmu=b*c;
165             expArr[0]=a+"÷"+c+"=";
166             System.out.println(expArr[0]);
167             results[i]=reductionofFraction(fenzi, fenmu);*/
168             
169         }
170         
171         }   
172      FileWriter fw = null;
173     try {
174    
175         File f=new File("Exersies.txt");//题目写入
176         fw = new FileWriter(f, true);
177     } catch (IOException e) {
178         e.printStackTrace();
179     }if(expArr[0]!=null) {
180     PrintWriter pw = new PrintWriter(fw);
181     pw.println(i+1+"."+expArr[0]);
182     pw.flush();
183     try {
184         fw.flush();
185         pw.close();
186         fw.close();
187     } catch (IOException e) {
188         e.printStackTrace();
189     }}FileWriter fn = null;
190     try {
191         
192             File f=new File("Answer.txt");//答案写入
193             fn = new FileWriter(f, true);
194         } catch (IOException e) {
195             e.printStackTrace();
196         }if(expArr[0]!=null) {
197         PrintWriter pn = new PrintWriter(fn);
198         pn.println(i+1+"."+results[i]);
199         pn.flush();
200         try {
201             fn.flush();
202             pn.close();
203             fn.close();
204         } catch (IOException e) {
205             e.printStackTrace();
206         }}
207     }
208      System.out.println("输入ok提交!");
209      Scanner sc1=new Scanner(System.in);
210      String submit=sc1.nextLine();
211         if(submit.equals("ok")){
212      String array[]=new String[num];
213      try
214         {   int k=0;
215             
216             FileReader fr = new FileReader("H://eclipse2//eclipse3//sizeyusuan//Your_answers.txt");
217             BufferedReader br = new BufferedReader(fr);
218             String s ;
219             while((s = br.readLine())!=null) {//读取小学生的答案
220                 array[k]=s;    k++;
221                 }br.close();
222             fr.close();        
223             }catch(IOException e){
224                 System.out.println("指定文件不存在");
225             }
226     for(int j=0;j<num;j++){
227          if(array[j].equals(results[j])) {//验证答案,统计正确和错误的个数
228              
229              rightcount[j]=j+1;
230              right1++;
231          }
232          else {
233              
234              wrongcount[j]=j+1;
235              wrong1++;
236          }
237      }
238     FileWriter fg = null;
239     try {
240         //反馈正确与错误题目的信息
241             File f=new File("Grade.txt");
242             fg = new FileWriter(f, true);
243         } catch (IOException e) {
244             e.printStackTrace();
245         }
246         PrintWriter pg = new PrintWriter(fg);
247         pg.println(" ");
248         pg.print("Correct:"+right1+"(");
249         for (int j = 0; j <= num; j++) {
250             if (rightcount[j] != 0) {
251                  pg.print(rightcount[j] + ",");
252             }
253         }
254         pg.println(")");
255         pg.print("Wrong:"+wrong1+"(");
256         for (int j = 0; j <= num; j++) {
257             if (wrongcount[j] != 0) {
258                  pg.print(wrongcount[j] + ",");
259             }
260         }
261         pg.print(")");
262         pg.flush();
263         try {
264             fg.flush();
265             pg.close();
266             fg.close();
267         } catch (IOException e) {
268             e.printStackTrace();
269         }}
270 }
271 }

  2)测试用例设计 (结合单元测试的内容和模块功能设计测试用例)

  新建一个名为 JUnit_Test 的项目,在其中编写一个 xiaoxuesheng 类。

  开发一个自动生成小学四则运算题目的命令行 “软件”。实现 输入你要出题的个数,随机产生四则运算,然后用户回答,并且进行打分。

  规则:用随机数实现100以内的加、减、乘、除运算,其中和与积不能超过100,差不为负(即须大减小),商不为小数或分数(即必须整除)。

  要求总计输出10个运算式,每输出一个运算式,等待输入结果,然后进行对错判断并输出。最后输出统计答对的题数与分然后对这些功能进行单元测试。

  3)选择的测试框架介绍、安装过程

  将 JUnit4 单元测试包引入这个项目,在该项目上点击右键找属性,在弹出的属性窗口中,首先在左边选择“Java Build Path”,然后到右上选择“Libraries” 标签,之后在   最右边点击“Add Library…按钮,然后在新弹出的对话框中选择 JUnit4 并点击确定,如上图所示,JUnit4 软件包就被包含进我们这个项目了。

  生成 JUnit 测试框架:在 Eclipse 的 Package Explorer 中用右键点击该类弹出菜单,选择“JUnit 测试用例”。在弹出的对话框中,进行相应的选择,如下图。

 

 4 )测试代码

点击“下一步”后,系统会自动列出你这个类中包含的方法,选择你要进行测试的方法。此例中,我们仅对下图所勾选的选项进行测试。

之 后 系 统 会 自 动 生 成 一 个 新 类CalculatorTest,里面包含一些空的测试用例。

  5)测试结果与分析

  每一个测试方法上使用@Test进行修饰; 每一个测试方法必须使用public void 进行修饰;每一个测试方法不能携带参数

  测试代码和源代码在两个不同的项目路径下;测试类的包应该和被测试类保持一致;测试单元中的每个方法必须可以独立测试。

  运行测试代码:按照上述代码修改完毕后,我们在 CalculatorTest 类上点右键,选择“Run As ——>JUnit Test”来运行我们的测试。

  具体的测试结果在进度条上面有表示“共进行了 3个测试,其中3个测试失败”。

 

 3、push测试报告和测试代码到各自的github仓库

出现这个问题的最主要原因在于本地仓库和远程仓库实际上是独立的两个仓库  ,这就相当于你想直接拿一个不相干的仓库去覆盖另一个远程库, 肯定不会同意

 这时, 只要,使用这个git pull --rebase origin master。此时再使用git push origin master就可以成功将文件 push 到你的远程仓库了。

思考题:

比较以下二个工匠的做法,你认为哪种好?结合编码和单元测试,谈谈你的认识。

我觉得这两种做法都有可取之处,工匠一的做法相当于是每编写一行代码就进行测试,在后面不会因为总的测试出现大量返工的情况,

但是会浪费很多时间。工匠二的做法固然节省时间,但如果出现大量错误改起来很费事。但我觉得孰能生巧,长时间编程错误率应该

不高,采取类似工匠二的做法很好。

实验小结

此次实验对我来说是针对本学期实验的总结,通过这次实验我对 git 实验和结对编程实验进行了一次回顾,更加熟练的掌握了实验方法,

对本地仓库及远程仓库之间的操作熟记于心。同时掌握了新的一种测试代码的工具,eclipse 中的 junit 插件真的很好用。

原文地址:https://www.cnblogs.com/321ending/p/13024778.html