0
点赞
收藏
分享

微信扫一扫

JUnit4快速入门(转)


JUnit4快速入门(转)


2008-08-06 10:47



JUnit 4是JUnit框架有史以来的最大改进,其主要目标便是利用Java 5的Annotation特性简化测试用例的编写。让我们看看如何使用JUnit 4来进行Unit测试。

请注意:本文主要介绍JUnit 4的最新特性和用法,并不会讲解Unit测试的基础。

我们使用的开发环境是Eclipse 3.2 ,它已经自带了JUnit 4.1,你需要将JUnit 4 Library添加到项目用到的Library中。另外,必须使用JDK 5.0 或更高版本。

要在Eclipse环境之外运行JUnit,需要下载JUnit 4.1,具体请访问JUnit.org 。

我们先看一个简单的Math类:



package         com.javaeedev.junit4;
 public   class         Math {

      public   int  abs( int         value) {
          return  value >= 0   ?  value : ( -        value);
      }

      public   int  div( int  a,  int         b) {
          return  a  /         b;
      }

      /**        
      * BUG: if b less than 0!
              */        
            public   float  exp( int  a,  int         b) {
          float  r  =   1        ;
          for ( int  i = 0 ; i < b; i ++        )
              r  =  r  *         a;
          return         r;
      }
 }



注意exp()方法是有Bug的,如果传入参数2, -1,则期待的返回值应为0.5F,但实际返回值为1.0F。

下面我们看看传统的JUnit的TestCase:



public   class  MathTest  extends         TestCase {

      public   void  setUp() {  super        .setUp(); }
      public   void  tearDown() {  super        .tearDown(); }

      public   void  testAbs() { assertTrue( true        ); }
      public   void         testDiv() {...}
      public   void         testExp() {...}

 }




JUnit依赖反射来执行每个以test开头的方法。然而,在最新的JUnit 4中,由于有了Annotation的支持,我们的测试方法不需要再以testXxx标识了,而是写上一个@Test标注即可。例如:



@Test  public   void  doAbs() {...}




甚至MathTest类也不必继承自TestCase。你也许会想到,不继承自TestCase就无法调用assertXxx方法了,正因为如此,所有的assertXxx方法全部以静态方法被放入了Assert类,使用Assert.assertXxx()调用。如果使用




import   static  org.junit.Assert. * ;




则原有的代码不必改动。

setUp()和tearDown()方法也依赖@Before和@After标记,这样做的最大的好处是在继承体系内不必担心忘记了在setUp()方法中调用父类的super.setUp()方法,JUnit框架会自动处理父类的@Before和@After标记的方法。

并且,JUnit框架对@Before和@After的调用顺序类似于类的构造方法和析构方法,即@Before按照父类到子类的顺序调用,@After则相反,这样保证了资源的正确获取和释放。

当然,不再强迫必须使用setUp和tearDown作为方法名,可以使用更有意义的方法名,例如:initDatabase()和closeDatabase(),只要它们被标注了@Before和@After即可。

来看看使用Annotation的MathTest:



package         com.javaeedev.junit4;

 import   static  org.junit.Assert. *        ;

 import  org.junit. *        ;

 public   class         MathTest {

      public         MathTest() {
          System.out.println( " new MathTest instance. "        );
      }

      @Before
      public   void  setUp()  throws         Exception {
          System.out.println( " call @Before before a test method "        );
      }

      @After
      public   void  tearDown()  throws         Exception {
          System.out.println( " call @After after a test method "        );
      }

      @Test
      public   void         doAbs() {
          Math math  =   new         Math();
          assertEquals( 200 , math.abs( 200        ));
          assertEquals( 100 , math.abs( - 100        ));
          assertEquals( 0 , math.abs( 0        ));
      }

      @Test
      public   void         doDiv() {
          Math math  =   new         Math();
          assertEquals( 5 , math.div( 100 ,  20        ));
          assertEquals( 4 , math.div( 100 ,  21        ));
      }

      @Test(expected = ArithmeticException. class        )
      public   void         doDiv0() {
          new  Math().div( 127 ,  0        );
      }

      @Test(timeout = 1        )
      public   void         doLongTimeTask() {
          double  d  =   0        ;
          for ( int  i = 1 ; i < 10000000 ; i ++        )
              d +=        i;
      }

      @Test
      public   void         testExp() {
          Math math  =   new         Math();
          assertEquals(32f, math.exp( 2 ,  5 ),  0.001f        );
          assertEquals(1f, math.exp( 2 ,  0 ),  0.001f        );
          assertEquals( 0.5f , math.exp( 2 , ( - 1 )),  0.001f        );
      }

 }




对测试异常,JUnit 4可以用expected=Exception.class



try         {
    ...
    fail( " No exception "        );
 }
 catch        (Exception e) {
    //  OK!        
        }


来看看doDiv0测试,我们期待一个除数为0的ArithmeticException,因此编写如下测试方法:



@Test(expected = ArithmeticException. class        )
 public   void         doDiv0() {
      new  Math().div( 127 ,  0        );
 }



对于非常耗时的测试,@Test还有一个timeout来标识该方法最长执行时间,超过此时间即表示该测试方法失败:



@Test(timeout = 1        )
 public   void         doLongTimeTask() {
      double  d  =   0        ;
      for ( int  i = 1 ; i < 10000000 ; i ++        )
          d +=        i;
 }



以上方法若执行时间超过1ms则测试失败,由于依赖CPU的执行速度,在不同的机器上测试结果也不同。

JUnit 4另一个较大的变化是引入了@BeforeClass和@AfterClass,它们在一个Test类的所有测试方法执行前后各执行一次。这是为了能在@BeforeClass中初始化一些昂贵的资源,例如数据库连接,然后执行所有的测试方法,最后在@AfterClass中释放资源。

正如你能想到的,由于@BeforeClass和@AfterClass仅执行一次,因此它们只能标记静态方法,在所有测试方法中共享的资源也必须是静态引用:




private   static         Object dbConnection;

 @BeforeClass
 public   static   void  setUpBeforeClass()  throws         Exception {
      System.out.println( " call @BeforeClass and init database connection "        );
      dbConnection  =   new         Object();
 }

 @AfterClass
 public   static   void  tearDownAfterClass()  throws         Exception {
      System.out.println( " call @AfterClass to release database connection "        );
      dbConnection  =   null        ;



举报

相关推荐

0 条评论