首页 > 代码库 > Java Junit测试框架

Java Junit测试框架

                                                Java    Junit测试框架

1、相关概念

? JUnit:是一个开发源代码的Java测试框架,用于编写和运行可重复的测试。它是用于单元测试框架体系xUnit的一个实例(用于java语言)。主要用于白盒测试,回归测试。
? 白盒测试:把测试对象看作一个打开的盒子,程序内部的逻辑结构和其他信息对测试人
员是公开的。
? 回归测试:软件或环境的修复或更正后的再测试,自动测试工具对这类测试尤其有用。
? 单元测试:最小粒度的测试,以测试某个功能或代码块。一般由程序员来做,因为它需要知道内部程序设计和编码的细节。

2、 单元测试

2.1、单元测试的好处
? 提高开发速度,测试是以自动化方式执行的,提升了测试代码的执行效率。
? 提高软件代码质量,它使用小版本发布至集成,便于实现人员除错。同时引入重构概念,让代码更干净和富有弹性。
? 提升系统的可信赖度,它是回归测试的一种。支持修复或更正后的“再测试”,可确保代码的正确性。

2.2、单元测试的针对对象
? 面向过程的软件开发针对过程。
? 面向对象的软件开发针对对象。
? 可以做类测试,功能测试,接口测试(最常用于测试类中的方法)。

2.3、单元测试工具和框架
目前的最流行的单元测试工具是xUnit系列框架,常用的根据语言不同分为JUnit(java),CppUnit(C++),DUnit (Delphi ),NUnit(.net),PhpUnit(PHP )等等。
单元测试框架的第一个和最杰出的应用就是由Erich Gamma (《设计模式》的作者)和Kent Beck(XP(Extreme Programming)的创始人 )提供的开放源代码的JUnit。

3、Junit入门简介

3.1、JUnit的好处和JUnit测试编写原则
使用JUnit的好处:
? 可以使测试代码与产品代码分开。
? 针对某一个类的测试代码通过较少的改动便可以应用于另一个类的测试。
? 易于集成到测试人员的构建过程中,JUnit和Ant的结合可以实施增量开发。
? JUnit是公开源代码的,可以进行二次开发。
? 可以方便地对JUnit进行扩展。

JUnit测试编写原则:
? 简化测试的编写,这种简化包括测试框架的学习和实际测试单元的编写。
? 使测试单元保持持久性。
? 可以利用既有的测试来编写相关的测试。

3.2、JUnit的特征
? 使用断言方法判断期望值和实际值差异,返回Boolean值。
? 测试驱动设备使用共同的初始化变量或者实例。
? 测试包结构便于组织和集成运行。
? 支持图型交互模式和文本交互模式。

3.3 JUnit框架组成
? 对测试目标进行测试的方法与过程集合,可称为测试用例(TestCase)。
? 测试用例的集合,可容纳多个测试用例(TestCase),将其称作测试包(TestSuite)。
? 测试结果的描述与记录。(TestResult) 。
? 测试过程中的事件监听者(TestListener)。
? 每一个测试方法所发生的与预期不一致状况的描述,称其测试失败元素(TestFailure)
? JUnit Framework中的出错异常(AssertionFailedError)。

    JUnit框架是一个典型的Composite模式:TestSuite可以容纳任何派生自Test的对象;当调用TestSuite对象的run()方法是,会遍历自己容纳的对象,逐个调用它们的run()方法。3.5 JUnit中常用的接口和类

? Test接口:运行测试和收集测试结果

    Test接口使用了Composite设计模式,是单独测试用例(TestCase),聚合测试模式(TestSuite)及测试扩展(TestDecorator)的共同接口。 它的public int countTestCases()方法,用来统计测试时有多少个TestCase。另外一个方法就是public void run( TestResult ),TestResult是实例接受测试结果, run方法执行本次测试。

? TestCase抽象类:定义测试中固定方法

    TestCase是Test接口的抽象实现,(不能被实例化,只能被继承)其构造函数TestCase(string name)根据输入的测试名称name创建一个测试实例。由于每一个TestCase在创建时都要有一个名称,若测试失败了,便可识别出是哪个测试失败。
TestCase类中包含的setUp()、tearDown()方法。

    setUp()方法集中初始化测试所需的所有变量和实例,并且在依次调用测试类中的每个测试方法之前再次执行setUp()方法。
tearDown()方法则是在每个测试方法之后,释放测试程序方法中引用的变量和实例。

    开发人员编写测试用例时,只需继承TestCase,来完成run方法即可,然后JUnit获得测试用例,执行它的run方法,把测试结果记录在TestResult之中。

? Assert静态类:一系列断言方法的集合

    Assert包含了一组静态的测试方法,用于期望值和实际值比对是否正确,即测试失败,Assert类就会抛出一AssertionFailedError异常,JUnit测试框架将这种错误归入Failes并加以记录,同时标志为未通过测试。如果该类方法中指定一个String类型的传参则该参数将被做为AssertionFailedError异常的标识信息,告诉测试人员改异常的详细信息。

    JUnit 提供了6大类31组断言方法,包括基础断言、数字断言、字符断言、布尔断言、对象断言。其中assertEquals(Object expcted,Object actual)内部逻辑判断使用equals()方法,这表明断言两个实例的内部哈希值是否相等时,最好使用该方法对相应类实例的值进行比较。

    而assertSame(Object expected,Object actual)内部逻辑判断使用了Java运算符“==”,这表明该断言判断两个实例是否来自于同一个引用(Reference),最好使用该方法对不同类的实例的值进行比对。
asserEquals(String message,String expected,String actual)该方法对两个字符串进行逻辑比对,如果不匹配则显示着两个字符串有差异的地方。

    ComparisonFailure类提供两个字符串的比对,不匹配则给出详细的差异字符。

? TestSuite测试包类??多个测试的组合

    TestSuite类负责组装多个Test Cases。待测得类中可能包括了对被测类的多个测试,而TestSuit负责收集这些测试,使我们可以在一个测试中,完成全部的对被测类的多个测试。TestSuite类实现了Test接口,且可以包含其它的TestSuites。它可以处理加入Test时的所有抛出的异常。

TestSuite处理测试用例有6个规约(否则会被拒绝执行测试)
2 测试用例必须是公有类(Public)
2 用例必须继承与TestCase类
2 测试用例的测试方法必须是公有的( Public )
2 测试用例的测试方法必须被声明为Void
2 测试用例中测试方法的前置名词必须是test
2 测试用例中测试方法误任何传递参数

? TestResult结果类和其它类与接口
    TestResult结果类集合了任意测试累加结果,通过TestResult实例传递个每个测试的Run()方法。TestResult在执行TestCase是如果失败会异常抛出。 

    TestListener接口是个事件监听规约,可供TestRunner类使用。它通知listener的对象相关事件,方法包括测试开始startTest(Test test),测试结束endTest(Test test),错误,增加异常addError(Test test,Throwable t)和增加失败addFailure(Test test,AssertionFailedError t)。

    TestFailure失败类是个“失败”状况的收集类,解释每次测试执行过程中出现的异常情况。其toString()方法返回“失败”状况的简要描述

4、Eclipse中JUnit的使用

    测试对于保证软件开发质量有着非常重要的作用,单元测试更是必不可少,JUnit是一个非常强大的单元测试包,可以对一个/多个类的单个/多个方法测试,还可以将不同的TestCase组合成TestSuit,使测试任务自动化。
Eclipse同样集成了JUnit,可以非常方便地编写TestCase。Eclipse自带了一个JUnit的插件,不用安装就可以在你的项目中开始测试相关的类,并且可以调试你的测试用例和被测试类。

4.1、Eclipse中JUint使用步骤

以下步骤环境为Eclipse SDK 3.2.2及JUnit3.8.1
? 新建一个测试用例或选择已有的所想测试的JAVA文件,点击“File->New->…”菜单项或右击文件,在弹出的“New”对话框中选择“JUnit Test Case”,就进入“New JUnit Test Case”对话框

? 在“New JUnit TestCase”对话框填写相应的栏目,主要有Name(测试用例名),SuperClass(若JUnit的版本是3.8.1,则测试的超类一般默认为junit.framework.TestCase; 若JUnit版本是JUnit 4.4,则默认超类为java.lang.Object。),Class Under Test(被测试的类),Source Folder(测试用例保存的目录),Package(测试用例包名),及是否自动生成main,setUp,tearDown方法。在此一般填写NAME及选上复选上setUpt和teardown即可。

? 点击“Next>”按钮,则进入Test Methods,在此你可以直接勾选你想测试的被测试类的方法,Eclipse将自动生成与被选方法相应的测试方法,点击“Fishish”按钮后一个测试用例就创建好了。

? 编写完成测试用例后,点击“Run”按钮就可以看到运行结果了。

    补充:要使用JUnit,您必须首先将JUnit JAR保存在项目的Build路径上并创建一个测试类。将JUnit保存在项目的Build路径上的步骤为:

    右击项目—>选择菜单底部的Properties选择Java Build Path—>选择Libraries—>点击Add Variable按钮—>查看已有的列表中有无JUnit文件,若没有,则点击Configure Variable—>New按钮,输入JUNIT_LIB作为变量名称,编辑该变量并指向解压后的JUnit目录中的一个名为JUnit.jar的文件—>然后在选择刚才添加的jar文件依次点击OK即可。

4.2、Eclipse中JUnit应用示例

    下面我们作一个在Eclipse中利用JUnit对HelloWorld的测试 测试方法:
? HelloWorld.sayHello()是否执行正常,并且结果也符合要求
? HelloWorld.add()方法是否与我们预期一样执行

    下一步,我们准备对这两个方法进行测试,确保功能正常。选中HelloWorld.java,右键点击,选择New->JUnit Test Case:

    进入下面这个页面,在此诸多栏目已经填好,即是这个需要测试的文件的相关信息,若是想在测试完之后即删除测试文件,也可更改路径。(本机在Eclipse已有的JUnit3.8.1的基础上又添加了一个新版本JUnit4.4)

    点击Next进入Test Methods,在此选择所要测试的方法sayHello及add。

    点击Finish,最后编写完成测试用例代码如下:

    直接运行Run->Run As->JUnit Test,就可以看到JUnit测试结果:

    绿色表示测试通过,只要有1个测试未通过,就会显示红色并列出未通过测试的方法。

5、后记

    从上面的来看,JUnit的使用并不很难,但关键就是最后一步完成测试码,即编写TestCase。要编写一个好的TestCase却并非易事。一个不好的TestCase往往是既浪费了时间,也起不了实际的作用。相反,一个好的TestCase,不仅可以很好的指出代码中存在的问题,而且也可以作为代码更准确的文档,同时还在持续集成的过程中起非常重要的作用。我们在作测试写TestCase时需要注意的几点:

? 测试的独立性:一次只测试一个对象,方便定位出错的位置。这有两层意思:一个TestCase,只测试一个对象;一个TestMethod,只测试这个对象中的一个方法。

? 给测试方法一个合适的名字。 一般取名为原来的方法名后加一个Test。

? 在assert函数中给出失败的原因,如:assertTrue( “… should be true”, ……),方便查错。在这个例子中,如果无法通过assertTrue,那么给出的消息将被显示。在junit中每个assert函数都有第一个参数是出错时显示消息的函数原型。

? 测试所有可能引起失败的地方,如:一个类中频繁改动的函数。对于那些仅仅只含有getter/setter的类,如果是由IDE(如Eclipse)产生的,则可不测;如果是人工写,那么最好测试一下。

? 在setUp和tearDown中的代码不应该是与测试方法相关的,而应该是全局相关的。如针对与测试方法A和B,在setUp和tearDown中的代码应该是A和B都需要的代码。

? 测试代码的组织:相同的包,不同的目录。这样,测试代码可以访问被测试类的protected变量/方法,方便测试代码的编写。放在不同的目录,则方便了测试代码的管理以及代码的打包和发布。

阐述JUnit的测试流程架构。我们将从不同的角度来详细分析这个图。

技术分享
图 测试序列图

 

 

TestNG和JUnit是针对Java语言的两个比较常用的测试框架。JUnit出现的比较早,但是早期的JUnit 3对测试代码有非常多的限制,使用起来很不方便,后来的JUnit 4得到很大的改进。TestNG的出现介于JUnit 3和JUnit 4,但是TestNG在很多方面还要优于JUnit 4。下面从整体上对TestNG和JUnit 4进行比较全面的比较。


  TestNG与JUnit的相同点:
1. 使用annotation,且大部分annotation相同。
2. 都可以进行单元测试(Unit test)。
3. 都是针对Java测试的工具。


  TestNG与JUnit的不同点:
1. JUnit只能进行单元测试,TestNG可以进行单元测试(unit test),功能测试(function test),端到端测试(e2e test),集成测试(Integration test)等。
2. TestNG需要一个额外的xml配置文件,配置测试的class、method甚至package。
3. TestNG的运行方式更加灵活:命令行、ant和IDE,JUnit只能使用IDE。
4. TestNG的annotation更加丰富,比如@ExpectedExceptions、@DataProvider等。
5. 测试套件运行失败,JUnit 4会重新运行整个测试套件。TestNG运行失败时,会创建一个XML文件说明失败的测试,利用这个文件执行程序,就不会重复运行已经成功的测试。


  TestNG比JUnit 4灵活性的体现:
1. JUnit 4中必须把@BeforeClass修饰的方法声明为public static,这就限制了该方法中使用的变量必须是static。而TestNG中@BeforeClass修饰的方法可以跟普通函数完全一样。
2. JUnit 4测试的依赖性非常强,测试用例间有严格的先后顺序。前一个测试不成功,后续所有的依赖测试都会失败。TestNG 利用@Test 的dependsOnMethods属性来应对测试依赖性问题。某方法依赖的方法失败,它将被跳过,而不是标记为失败。
3. 对于n个不同参数组合的测试,JUnit 4要写n个测试用例。每个测试用例完成的任务基本是相同的,只是受测方法的参数有所改变。TestNG的参数化测试只需要一个测试用例,然后把所需要的参数加到TestNG的xml配置文件中。这样的好处是参数与测试代码分离,非程序员也可以修改参数,同时修改无需重新编译测试代码。
4. 为了测试无法用String或原语值表示的复杂参数化类型,TestNG提供的@DataProvider使它们映射到某个测试方法。
5. JUnit 4的测试结果通过Green/Red bar体现,TestNG的结果除了Green/Red bar,还有Console窗口和test-output文件夹,对测试结果的描述更加详细,方便定位错误。


  简单说就是TestNG比Junit强大, 但是那些更强大的功能你全部都用不到的话, 那你还是就用junit, 比较简单, 国人用的多, 出了问题中文也比较好查.  英文还不错并且有想要了解除了单元测试以外的测试的话, 就用TestNG吧。


详解Java单元测试Junit框架实例

主要介绍了Java的异常测试框架JUnit使用上手指南,JUnit是Java代码进行单元测试中的常用工具,
 

问题:

1、目前测试存在的问题

2、Junit注意的细节

3、Junit使用规范

4、断言

5、案例

junit(单元测试框架)

1、目前存在的问题

1、目前的测试方法如果需要测试,都需要在main方法上调用

2、目前的结果都需要我们人工比对

2、Junit 注意的细节

1、如果使用junit测试一个方法的时候,在junit窗口上显示绿色那么表示测试正确,如果显示了红色,则代表该方法测试出现了异常不通过

2、如果点击方法名、类名、包名、工程名运行junit分别测试的是对于的方法,类、包中的所有类的test方法,工程中所有test的方法

3、@Test测试的方法不能是static修饰与不能带有形参

4、如果测试一个方法的时候需要准备测试的环境或者是清理测试的环境,那么可以@Before、@After、@BeforeClass、@AfterClass 这四个注释,@Before、@After 是在每个测试方法测试的时候都会调用一次,@AfterClass、@BeforeClass是在所有的测试方法测试之前与之后都会调用一次,这个方法必须是静态的

3、junit使用规范

1、一个类如果需要测试,那么该类就应该对应着一个测试类,测试类的命名规范:被测试类的类名+Test

2、一个被测试的方法一般对应一个测试的方法,测试的方法的命名规范是:test+被测试的方法的方法名

4、断言

断言就是不显示结果,按照程序运行的预期值和实际值进行比对,显示运行的状态。

?
1
2
3
4
5
Assert.assertSame(5, max); // 底层是用了  ==
Assert.assertSame(new String("abc"), "abc");
Assert.assertEquals(new String("abc"), "abc"); //底层是使用Equals方法比较的
Assert.assertNull("aa");
Assert.assertTrue(true);

5、案例

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
package cn.xlucas.junit;
import java.io.*;
import org.junit.*;
public class JunitDemo1 {
  //准备测试的环境
  //@Before
  @BeforeClass
  public static void beforeRead(){
    System.out.println("准备测试环境成功...");
  }
  //读取文件数据,把把文件数据都
  @Test
  public void readFile() throws IOException{
    FileInputStream fileInputStream = new FileInputStream("F:\\a.txt");
    int content = fileInputStream.read();
    System.out.println("内容:"+content);
  }
  @Test
  public void sort(){
    System.out.println("读取文件数据排序..");
  }
   //清理测试环境的方法
// @After 
  @AfterClass
  public static void afterRead(){
    System.out.println("清理测试环境..");
  }
}
 

一、JUnit4是JUnit框架有史以来的最大改进,其主要目标便是利用Java5的Annotation特性简化测试用例的编写。


 


二、先简单解释一下什么是Annotation,这个单词一般是翻译成元数据。元数据是什么?元数据就是描述数据的数据。也就是说,这个东西在Java里面可以用来和public、static等关键字一样来修饰类名、方法名、变量名。修饰的作用描述这个数据是做什么用的,差不多和public描述这个数据是公有的一样


 


三、Person类的方法进行测试


 


测试类Person:


 


[java] view plain copy
  1. package com.ren.junit;  
  2.   
  3. public class Person {  
  4.       
  5.     private String name;  
  6.     private int age;  
  7.       
  8.     public String getName() {  
  9.         return name;  
  10.     }  
  11.     public void setName(String name) {  
  12.         this.name = name;  
  13.     }  
  14.     public int getAge() {  
  15.         return age;  
  16.     }  
  17.     public void setAge(int age) {  
  18.         this.age = age;  
  19.     }  
  20. }  
 

测试该类的方法PersonTest:


[java] view plain copy
  1. package com.ren.junit;  
  2.   
  3. import org.junit.After;  
  4. import org.junit.AfterClass;  
  5. import org.junit.Before;  
  6. import org.junit.BeforeClass;  
  7. import org.junit.Test;  
  8.   
  9. //对Person类进行测试  
  10. public class PersonTest {  
  11.   
  12.     private Person p;  
  13.       
  14.     @BeforeClass  
  15.     public static void beforeClass() {  
  16.         System.out.println("boforeClass");  
  17.     }  
  18.       
  19.     @Before  
  20.     public void before() {  
  21.         p = new Person("lisi",20);  
  22.         System.out.println("before");  
  23.     }  
  24.       
  25.     @Test  
  26.     public void testGetName() {  
  27.           
  28.         System.out.println(p.getName());  
  29.     }  
  30.       
  31.     @Test  
  32.     public void testGetAge() {  
  33.           
  34.         System.out.println(p.getAge());  
  35.     }  
  36.       
  37.     @After  
  38.     public void after() {  
  39.         System.out.println("after");  
  40.     }  
  41.   
  42.     @AfterClass  
  43.     public static void afterClass() {  
  44.         System.out.println("afterClass");  
  45.     }  
  46. }  
  47.   
  48. 输出结果:  
  49. boforeClass  
  50. before  
  51. lisi  
  52. after  
  53. before  
  54. 20  
  55. after  
  56. afterClass  



以下是转载:


我们先看一下在JUnit 3中我们是怎样写一个单元测试的。比如下面一个类:


 


[java] view plain copy
  1. public class AddOperation {  
  2.       public int add(int x,int y){  
  3.           return x+y;  
  4.       }  
  5. }  

我们要测试add这个方法,我们写单元测试得这么写:




[java] view plain copy
  1. import junit.framework.TestCase;  
  2. import static org.junit.Assert.*;  
  3. public class AddOperationTest extends TestCase{  
  4.   
  5.       public void setUp() throws Exception {  
  6.       }  
  7.   
  8.       public void tearDown() throws Exception {  
  9.       }  
  10.   
  11.       public void testAdd() {  
  12.           System.out.println(\"add\");  
  13.           int x = 0;  
  14.           int y = 0;  
  15.           AddOperation instance = new AddOperation();  
  16.           int expResult = 0;  
  17.           int result = instance.add(x, y);  
  18.           assertEquals(expResult, result);  
  19.       }  
  20. }  



可以看到上面的类使用了JDK5中的静态导入,这个相对来说就很简单,只要在import关键字后面加上static关键字,就可以把后面的类的static的变量和方法导入到这个类中,调用的时候和调用自己的方法没有任何区别。


我们可以看到上面那个单元测试有一些比较霸道的地方,表现在:
1.单元测试类必须继承自TestCase。
2.要测试的方法必须以test开头。

如果上面那个单元测试在JUnit 4中写就不会这么复杂。代码如下:


[java] view plain copy
  1. import junit.framework.TestCase;  
  2. import org.junit.After;  
  3. import org.junit.Before;  
  4. import org.junit.Test;  
  5. import static org.junit.Assert.*;  
  6.   
  7. /** 
  8. * @author bean 
  9. */  
  10. public class AddOperationTest extends TestCase{  
  11.       
  12.       public AddOperationTest() {  
  13.       }  
  14.   
  15.       @Before  
  16.       public void setUp() throws Exception {  
  17.       }  
  18.   
  19.       @After  
  20.       public void tearDown() throws Exception {  
  21.       }  
  22.   
  23.       @Test  
  24.       public void add() {  
  25.           System.out.println(\"add\");  
  26.           int x = 0;  
  27.           int y = 0;  
  28.           AddOperation instance = new AddOperation();  
  29.           int expResult = 0;  
  30.           int result = instance.add(x, y);  
  31.           assertEquals(expResult, result);  
  32.       }  
  33.       
  34. }  



我们可以看到,采用Annotation的JUnit已经不会霸道的要求你必须继承自TestCase了,而且测试方法也不必以test开头了,只要以@Test元数据来描述即可。
从上面的例子可以看到在JUnit 4中还引入了一些其他的元数据,下面一一介绍:
@Before:
使用了该元数据的方法在每个测试方法执行之前都要执行一次。

@After:
使用了该元数据的方法在每个测试方法执行之后要执行一次。

注意:@Before和@After标示的方法只能各有一个。这个相当于取代了JUnit以前版本中的setUp和tearDown方法,当然你还可以继续叫这个名字,不过JUnit不会霸道的要求你这么做了。

@Test(expected=*.class)
在JUnit4.0之前,对错误的测试,我们只能通过fail来产生一个错误,并在try块里面assertTrue(true)来测试。现在,通过@Test元数据中的expected属性。expected属性的值是一个异常的类型

@Test(timeout=xxx):
该元数据传入了一个时间(毫秒)给测试方法,
如果测试方法在制定的时间之内没有运行完,则测试也失败。

@ignore:
该元数据标记的测试方法在测试中会被忽略。当测试的方法还没有实现,或者测试的方法已经过时,或者在某种条件下才能测试该方法(比如需要一个数据库联接,而在本地测试的时候,数据库并没有连接),那么使用该标签来标示这个方法。同时,你可以为该标签传递一个String的参数,来表明为什么会忽略这个测试方法。比如:@lgnore(“该方法还没有实现”),在执行的时候,仅会报告该方法没有实现,而不会运行测试方法。

 

 

junit测试是现在编写测试代码的手段之一,本文简要介绍如何快速搭建一个junit测试环境.

 

工具/原料

 
  • eclipse工具
  • junit包

 

方法/步骤

 

 

 

  1. 1

    首先创建一个java Project;将junit包和hamcrest-core包导入到项目中

    技术分享
  2. 2

    创建一个source folder 资源文件夹 test,资源文件夹和普通的文件夹区别是,资源文件夹中的java文件可以被自动编译。

    技术分享
    技术分享
  3. 3

    在java文件中编写java代码UserMananger.java,在test文件中创建一个与需要进行测试的java代码同包名称的TestUserManager.java文件。

    技术分享
  4. 4

    junit4采用的是通过注解的方式(在方法的上面加上@).

    @Before表示在所有方法运行前运行的方法;

    @After表示在所有的方法运行之后执行的方法;

    @Test表示这是一个测试方法

    @BeforeClass表示在这个测试类构造之前执行的方法

    @AfterClass表示在这个测试类构造之后执行的方法

    技术分享
  5. 5

    如果是对某一个方法进行测试,在方法的名称上点击右键 --> run as --> JUnit Test

    技术分享
  6. 6

    如果是对所有的方法都执行一遍,在类体上右键--Run as--> JunitTest .

    绿色的表示运行通过的方法,红x的表示运行失败的方法.

    技术分享
     
     
    本文简要介绍一下在Eclipse3.2中使用JUnit4进行单元测试的方法。

    首先,我们来一个傻瓜式速成教程,不要问为什么,Follow Me,先来体验一下单元测试的快感!

    首先新建一个项目叫JUnit_Test,我们编写一个Calculator类,这是一个能够简单实现加减乘除、平方、开方的计算器类,然后对这些功能进行单元测试。这个类并不是很完美,我们故意保留了一些Bug用于演示,这些Bug在注释中都有说明。该类代码如下:


    package andycpp;

    public class Calculator {
        private static int result; // 静态变量,用于存储运行结果
        public void add(int n) {
            result = result + n;
        }
        public void substract(int n) {
            result = result - 1;  //Bug: 正确的应该是 result =result-n
        }
        public void multiply(int n) {
        }         // 此方法尚未写好
        public void divide(int n) {
            result = result / n;
        }
        public void square(int n) {
            result = n * n;
        }
        public void squareRoot(int n) {
            for (; ;) ;           //Bug : 死循环
        }
        public void clear() {     // 将结果清零
            result = 0;
        }
        public int getResult() {
            return result;
        }
    }

    第二步,将JUnit4单元测试包引入这个项目:在该项目上点右键,点“属性”,如图:

     


    在弹出的属性窗口中,首先在左边选择“Java Build Path”,然后到右上选择“Libraries”标签,之后在最右边点击“Add Library…”按钮,如下图所示:


    然后在新弹出的对话框中选择JUnit4并点击确定,如上图所示,JUnit4软件包就被包含进我们这个项目了。

        第三步,生成JUnit测试框架:在EclipsePackage Explorer中用右键点击该类弹出菜单,选择“New à JUnit Test Case”。如下图所示:


    在弹出的对话框中,进行相应的选择,如下图所示:


        点击“下一步”后,系统会自动列出你这个类中包含的方法,选择你要进行测试的方法。此例中,我们仅对“加、减、乘、除”四个方法进行测试。如下图所示:


    之后系统会自动生成一个新类CalculatorTest,里面包含一些空的测试用例。你只需要将这些测试用例稍作修改即可使用。完整的CalculatorTest代码如下:


    package andycpp;

    import static org.junit.Assert.*;
    import org.junit.Before;
    import org.junit.Ignore;
    import org.junit.Test;

    public class CalculatorTest {

        private static Calculator calculator = new Calculator();
        
        @Before
        public void setUp() throws Exception {
            calculator.clear();
        }

        @Test
        public void testAdd() {
            calculator.add(2);
            calculator.add(3);
            assertEquals(5, calculator.getResult());
        }

        @Test
        public void testSubstract() {
            calculator.add(10);
            calculator.substract(2);
            assertEquals(8, calculator.getResult());
        }

        @Ignore("Multiply() Not yet implemented")
        @Test
        public void testMultiply() {
        }

        @Test
        public void testDivide() {
            calculator.add(8);
            calculator.divide(2);
            assertEquals(4, calculator.getResult());
        }
    }

    第四步,运行测试代码:按照上述代码修改完毕后,我们在CalculatorTest类上点右键,选择“Run As à JUnit Test”来运行我们的测试,如下图所示:

     

    运行结果如下:

     

     

    进度条是红颜色表示发现错误,具体的测试结果在进度条上面有表示“共进行了4个测试,其中1个测试被忽略,一个测试失败”

     

    我们继续对初级篇中的例子进行分析。初级篇中我们使用Eclipse自动生成了一个测试框架,在这篇文章中,我们来仔细分析一下这个测试框架中的每一个细节,知其然更要知其所以然,才能更加熟练地应用JUnit4。

    一、     包含必要地Package

    在测试类中用到了JUnit4框架,自然要把相应地Package包含进来。最主要地一个Package就是org.junit.*。把它包含进来之后,绝大部分功能就有了。还有一句话也非常地重要“import static org.junit.Assert.*;”,我们在测试的时候使用的一系列assertEquals方法就来自这个包。大家注意一下,这是一个静态包含(static),是JDK5中新增添的一个功能。也就是说,assertEquals是Assert类中的一系列的静态方法,一般的使用方式是Assert. assertEquals(),但是使用了静态包含后,前面的类名就可以省略了,使用起来更加的方便。

    二、     测试类的声明

    大家注意到,我们的测试类是一个独立的类,没有任何父类。测试类的名字也可以任意命名,没有任何局限性。所以我们不能通过类的声明来判断它是不是一个测试类,它与普通类的区别在于它内部的方法的声明,我们接着会讲到。

    三、     创建一个待测试的对象。

    你要测试哪个类,那么你首先就要创建一个该类的对象。正如上一篇文章中的代码:

     

    private static Calculator calculator = new Calculator();

     

    为了测试Calculator类,我们必须创建一个calculator对象。

    四、     测试方法的声明

    在测试类中,并不是每一个方法都是用于测试的,你必须使用“标注”来明确表明哪些是测试方法。“标注”也是JDK5的一个新特性,用在此处非常恰当。我们可以看到,在某些方法的前有@Before、@Test、@Ignore等字样,这些就是标注,以一个“@”作为开头。这些标注都是JUnit4自定义的,熟练掌握这些标注的含义非常重要。

    五、     编写一个简单的测试方法。

    首先,你要在方法的前面使用@Test标注,以表明这是一个测试方法。对于方法的声明也有如下要求:名字可以随便取,没有任何限制,但是返回值必须为void,而且不能有任何参数。如果违反这些规定,会在运行时抛出一个异常。至于方法内该写些什么,那就要看你需要测试些什么了。比如:

     

        @Test

        public void testAdd() {

              calculator.add(2);

              calculator.add(3);

              assertEquals(5, calculator.getResult());

        }

     

    我们想测试一下“加法”功能时候正确,就在测试方法中调用几次add函数,初始值为0,先加2,再加3,我们期待的结果应该是5。如果最终实际结果也是5,则说明add方法是正确的,反之说明它是错的。assertEquals(5, calculator.getResult());就是来判断期待结果和实际结果是否相等,第一个参数填写期待结果,第二个参数填写实际结果,也就是通过计算得到的结果。这样写好之后,JUnit会自动进行测试并把测试结果反馈给用户。

    六、     忽略测试某些尚未完成的方法。

    如果你在写程序前做了很好的规划,那么哪些方法是什么功能都应该实现定下来。因此,即使该方法尚未完成,他的具体功能也是确定的,这也就意味着你可以为他编写测试用例。但是,如果你已经把该方法的测试用例写完,但该方法尚未完成,那么测试的时候一定是“失败”。这种失败和真正的失败是有区别的,因此JUnit提供了一种方法来区别他们,那就是在这种测试函数的前面加上@Ignore标注,这个标注的含义就是“某些方法尚未完成,暂不参与此次测试”。这样的话测试结果就会提示你有几个测试被忽略,而不是失败。一旦你完成了相应函数,只需要把@Ignore标注删去,就可以进行正常的测试。

    七、     Fixture(暂且翻译为“固定代码段”)

    Fixture的含义就是“在某些阶段必然被调用的代码”。比如我们上面的测试,由于只声明了一个Calculator对象,他的初始值是0,但是测试完加法操作后,他的值就不是0了;接下来测试减法操作,就必然要考虑上次加法操作的结果。这绝对是一个很糟糕的设计!我们非常希望每一个测试都是独立的,相互之间没有任何耦合度。因此,我们就很有必要在执行每一个测试之前,对Calculator对象进行一个“复原”操作,以消除其他测试造成的影响。因此,“在任何一个测试执行之前必须执行的代码”就是一个Fixture,我们用@Before来标注它,如前面例子所示:

     

          @Before

          public void setUp() throws Exception {

               calculator.clear();

          }

     

    这里不在需要@Test标注,因为这不是一个test,而是一个Fixture。同理,如果“在任何测试执行之后需要进行的收尾工作”也是一个Fixture,使用@After来标注。由于本例比较简单,没有用到此功能。

            JUnit4的一些基本知识就介绍到此,还有一些更灵活的用法放在本系列的高级篇中给大家介绍!

     

     

    1.类的定义:类是同一事物的总称,类是封装对象的属性和行为的载体,反过来说具有相同属性和行为的一类实体被称为类。

     

    2.Junit工具的使用:

     

    第一步

     

    首先新建一个项目叫JUnit_Test,我们编写一个Calculator类,这是一个能够简单实现加减乘除、平方、开方的计算器类,然后对这些功能进行单体测试。

     

    第二步,将JUnit4单元测试包引入这个项目:在该项目上点右键,点“属性”,如图:技术分享

     

    在弹出的属性窗口中,首先在左边选择“Java Build Path”,然后到右上选择“Libraries”标签,之后在最右边点击“Add Library…”按钮,如下图所示

     

    技术分享

     

    然后在新弹出的对话框中选择JUnit4并点击确定,如上图所示,JUnit4软件包就被包含进我们这个项目了。

        第三步,生成JUnit测试框架:在Eclipse的Package Explorer中用右键点击该类弹出菜单,选择“New à JUnit Test Case”。如下图所示:

     

    技术分享

     

     

     

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

     

     

     

    之后系统会自动生成一个新类CalculatorTest,里面包含一些空的测试用例。你只需要将这些测试用例稍作修改即可使用。

     

    第四步,运行测试代码:按照上述代码修改完毕后,我们在CalculatorTest类上点右键,选择“Run As à JUnit Test”来运行我们的测试,如下图所示:

     

    技术分享

     

     

     

    运行结果如下:

     

    技术分享

     

    4.记录各个阶段的时间

    1.类的定义:类是同一事物的总称,类是封装对象的属性和行为的载体,反过来说具有相同属性和行为的一类实体被称为类。

    2.Junit工具的使用:

    第一步

    首先新建一个项目叫JUnit_Test,我们编写一个Calculator类,这是一个能够简单实现加减乘除、平方、开方的计算器类,然后对这些功能进行单体测试。

    第二步,将JUnit4单元测试包引入这个项目:在该项目上点右键,点“属性”,如图:技术分享

    在弹出的属性窗口中,首先在左边选择“Java Build Path”,然后到右上选择“Libraries”标签,之后在最右边点击“Add Library…”按钮,如下图所示

    技术分享

    然后在新弹出的对话框中选择JUnit4并点击确定,如上图所示,JUnit4软件包就被包含进我们这个项目了。

        第三步,生成JUnit测试框架:在Eclipse的Package Explorer中用右键点击该类弹出菜单,选择“New à JUnit Test Case”。如下图所示:

    技术分享

     

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

     

    之后系统会自动生成一个新类CalculatorTest,里面包含一些空的测试用例。你只需要将这些测试用例稍作修改即可使用。

    第四步,运行测试代码:按照上述代码修改完毕后,我们在CalculatorTest类上点右键,选择“Run As à JUnit Test”来运行我们的测试,如下图所示:

    技术分享

     

    运行结果如下:

    技术分享

    1、Junit简介:

        Junit最初是由Erich Gamma 和 Kent Beck 编写的一个回归测试框架(regression testing framework),为单元测试(Unit Test)的支持框架。用来编写和执行重覆性的测试。即所谓白盒测试。

     

    它包括了以下的特性:

     

      1 对预期结果作断言
      2 提供测试装备的生成与销毁
      3 易于组织执行测试
      4 图形与文字界面的测试器
    2、Junit的环境配置
    环境:Eclipse 中配置junit,选择项目Junit4(在Package Explorer中) -> 右击鼠标 -> 选择properties -> 选择Java Build Path (在左边的菜单中) -> 在右边选择标签 Libraries  -> 单击按钮“Add Library”  -> 选择JUnit , 单击按钮 “Next>”  -> 选择JUnit library version 为: JUnit4 -> 单击按钮“Finish” –> 单击按钮 “OK”

     

     Junit4是Junit框架有史以来的最大改进,其主要目标是利用java5的Annotation特性来简化测试用例的编写。Junit4的官方网址是http://www.junit.org/。

     

     

     

    3、总结一下3-4的不同,及4的改进

     

    下面我们以一个简单的例子来介绍如何使用 Junit4同Junit3编写测试用例:
    public Class XXXX{

     

         public String hello(){

     

         return “hello”;

     

          }

     

    }

     

    对于这个类的用junit3编写测试用例:

     

    import junit.framework.TestCase;

     

       public Class XXXXTest extends TestCase{

     

       public void testHello(){

     

       asssertEqual(new XXXX().Hello(),”hello”);

     

      }

     

    }

     

    用junit4编写测试用例:

     

    import static org.junit.framework.assertEqual;

     

    import org.junit.Test;

     

    //这两个是junit4中必须导入的s

     

    public Class XXXXTest{

     

    @Test

     

    public void helloTest(){

     

        asssertEqual(new XXXX().Hello(),”hello”);

     

    }

     

    }

     

    从上面例子我们对Junit3和Junit4有了一个初步的印象,下面我们重点介绍Junit4与Junit3的主要区别。

     

    JUnit3  JUnit4
    必须引入类TestCase
    import junit.framework.TestCase; 必须引入
    import org.junit.Test;
    import static org.junit.Assert.*;
    必须继承类TestCase
    class BaseClassTest extends TestCase 不需要
    测试方法必须以test开头
    public void testMethod () 不需要,
    但是类开始的时候要标记 @Test
    通过assert*方法来判断结果
    assertTrue(baseClass.method ().equals(“test.junit.BaseClass”));

     

     

 

 

 

Java Junit测试框架