`
032615
  • 浏览: 59924 次
  • 性别: Icon_minigender_1
  • 来自: 长沙
社区版块
存档分类
最新评论

JUnit单元测试

阅读更多

Junit是由 Erich Gamma 和 Kent Beck 编写的一个回归测试框架(regression testing framework),供Java开发人员编写单元测试之用。Junit测试是程序员测试,即所谓白盒测试。下面我们以一个简单的例子来介绍如何使用 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;

  public Class XXXXTest{

  @Test

  public void helloTest(){

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

  }

  }

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

  1.2 Junit4与Junit3的主要区别

  1.2.1 Junit4引入了java 5.0的注释技术:

  这两个版本最大的区别在JUnit3.x中测试必须继承 TestCase,并且每个方法名必须以test开头。比如:testMethod1()而在JUnit4.x中不必继承TestCase,采用了注解的方式。只要在测试的方法上加上注解@Test即可,从而不必再遵循以前的一些显式约定和反射定位测试;在JUnit4.x中如果继承了TestCase,注解就不起作用了。并且有很重要的一点就是在JUnit4.x中继承了TestCase后,在OutLine视图中测试单个方法时,结果整个类都run 了。还有一点就是,在3.x中需要实现setUp和tearDown方法,而在4.x中无需这样,可以自定义需要在测试前和测试后的方法,在方法前加上 @before,@after就可以了。所以在JUnit4.x不必继承TestCase用注解即可对单个方法进行测试。

  1.2.2 JUnit4引入了一个JUnit3中没有的新特性——类范围的 setUp() 和tearDown() 方法。

  任何用 @BeforeClass 注释的方法都将在该类中的测试方法运行之前刚好运行一次,而任何用 @AfterClass 注释的方法都将在该类中的所有测试都运行之后刚好运行一次。

  1.2.3 异常测试:

  异常测试是Junit4中的最大改进。Junit3的异常测试是在抛出异常的代码中放入try块,然后在try块的末尾加入一个fail()语句。

  例如该方法测试一个被零除抛出一个ArithmeticException:

  该方法不仅难看,而且试图挑战代码覆盖工具,因为不管测试是否通过还是失败,总有一些代码不被执行。在JUni4中,可以编写抛出异常的代码,并使用注释来声明该异常是预期的:

  如果没有异常抛出或者抛出一个不同的异常,那么测试就将失败。

  1.2.4 JUnit4添加了两个比较数组的assert() 方法:

  public static void assertEquals(Object[] expected, Object[] actual)

  public static void assertEquals(String message, Object[] expected, Object[] actual)

  这两个方法以最直接的方式比较数组:如果数组长度相同,且每个对应的元素相同,则两个数组相等,否则不相等。数组为空的情况也作了考虑。

  1.3 JUnit 4 常用的几个annotation 介绍

  ★ @Before:初始化方法,在任何一个测试执行之前必须执行的代码;

  ★ @After:释放资源,在任何测试执行之后需要进行的收尾工作;

  ★ @Test:测试方法,表明这是一个测试方法。对于方法的声明也有如下要求:名字可以随便取,没有任何限制,但是返回值必须为void,而且不能有任何参数。如果违反这些规定,会在运行时抛出一个异常。至于方法内该写些什么,那就要看你需要测试些什么了;在这里可以测试期望异常和超时时间,如 @Test(timeout = 100),我们给测试函数设定一个执行时间,超过了这个时间(100毫秒),它们就会被系统强行终止,并且系统还会向你汇报该函数结束的原因是因为超时,这样你就可以发现这些Bug了。

  ★ @Ignore:忽略的测试方法,标注的含义就是“某些方法尚未完成,暂不参与此次测试”;这样的话测试结果就会提示你有几个测试被忽略,而不是失败。一旦你完成了相应函数,只需要把@Ignore标注删去,就可以进行正常的测试。

  ★ @BeforeClass:针对所有测试,只执行一次,且必须为static void;

  ★ @AfterClass:针对所有测试,只执行一次,且必须为static void;

  所以一个Junit 4 的单元测试用例执行顺序为:@BeforeClass –> @Before –> @Test –> @After –> @AfterClass;每一个测试方法的调用顺序为:@Before –> @Test –> @After。

下面是一个比较完整的示例:
1. 简单Java类:
package com.qdl.action;
/**
 * This class includes all the methods that to be tested.
 * @author Kaven
 *
 */
public class HelloAction {
 public int addResult(int a,int b){
  return a + b;
 }
 
 public String trunString(String str){
  if(null==str||str.length()<3){
   return str;
  }else{
   return str.substring(2);
  }
 }
 
 public int divideResult(int a, int b) throws Exception{
  return a/b;
 }
}
 
2. 测试类:
package com.qdl.action;
import junit.framework.Assert;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
/**
 * In JUnit 4.x, we can use annotation and there is no need to extend TestCase Class.
 * If we extend TestCase class and meantime use annotation, then these annotations will be ignored.
 * @author Kaven
 *
 */
public class HelloActionTest{
 
 private static HelloAction action;
 
 @BeforeClass
 public static void doInitial() throws Exception {
  action = new HelloAction();
  System.out.println("JUnit test begin.");
 }
 
 @Before
 public void beforeTest(){
  // This is equivalent to setUp() method in JUnit 3.x version.
  System.out.println("Before a test method.");
 }
 
 @Test
 public void testAddResult(){
  int result = action.addResult(10, 20);
  Assert.assertEquals(result, 30);
 }
 //@Ignore
 @Test
 public void testSliceString(){
  String aa = null;
  Assert.assertEquals(action.trunString(aa), null);
  String bb = "bb";
  Assert.assertEquals(action.trunString(bb),bb);
  String cc = "ccc";
  Assert.assertEquals(action.trunString(cc),"c");
  
 }
 
 @Test
 //(expected = Exception.class)
 public void testDivideResult() throws Exception{
  Assert.assertEquals(2, action.divideResult(20, 10));
 }
 
 @After
 public void afterTest(){
  // This is equivalent to tearDown() method in JUnit 3.x version.
  System.out.println("After a test method.");
 }
 @AfterClass
 public static void doAfter() throws Exception {
  System.out.println("JUnit test end.");
 }
}
运行"Run as Junit test"可以查看结果。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics