JUnit使用介绍

JUnit基础

Junit编写测试方法的时候,默认只需要在方法上添加相关注解即可,所有的方法必须是无参数,无返回值的方法,否则JUint会报错,除去最常用的@Test注解外,方法上还可以添加一些其他的注解:

  • @BeforeClass:该注解标注的方法必须是静态方法,这个方法会在所有测试方法执行前会被调用。在对整个类进行测试时,只会被调用一次。
  • @Before:该注解标注的方法会在每个测试方法进行测试前执行一次,一般用于处理每个测试方法的数据初始化。
  • @Test:该注解标注的方法为测试方法。有两个属性,分别是timeout和expected,下文会介绍
  • @Ignore:该注解标注的方法在测试时会被忽略。必须与@Test使用,否则报错
  • @After:该注解标注的方法会在每个测试方法执行后执行一次,一般用于清理这个测试方法测试后的数据清理
  • @AfterClass:该注解标注的方法必须是静态方法,这个方法在所有测试完成之后会被调用。在对整个类进行测试时,只会调用一次。

代码示例:

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
public class JUnitTest {
    @BeforeClass
    public static void beforeClass(){
        System.out.println("beforeClass");
    }
    @Before
    public  void before(){
        System.out.println("before");
    }
    @Test
    public  void test(){
        System.out.println("test");
    }
    @Test
    public  void test2(){
        System.out.println("test2");
    }
    @Test
    @Ignore
    public  void ignore(){
        System.out.println("ignore");
    }
    @After
    public void after(){
        System.out.println("after");
    }
    @AfterClass
    public static void  afterClass(){
        System.out.println("afterClass");
    }
}

运行结果:

beforeClass
before
test
after
before
test2
after
afterClass

上述结果也可以看出,各个注解标注方法的执行顺序是:

@BeforeClass->@Before->@Test->@After->@Before->@Test->@After->…->@AfterClass

@Test属性

@Test注解有两个属性timeout和expected,分别如下:
- @Test(timeout=1000):限时测试方法,某些方法可能执行的时间比较长,我们有可能会限定这个方法的执行时间,因此在@Test注解上增加属性timeout可以设置这个方法的执行时间,如果没有在指定时间内执行完的话,则测试失败。单位为毫秒
- @Test(expected=ArithmeticException.class):expected用于检查抛出异常信息的代码,测试方法中的代码抛出了expected属性指定的异常,则该测试成功,否则失败。

代码示例:

@Test(timeout=1000)
public void timeout() throws InterruptedException{
    for(;;);
}
@Test(expected=ArithmeticException.class)
public void exception(){
    int i = 1/0;
}

如上述代码所示,timeout()方法中是一个死循环,永远都不会结束,该方法测试的结果是失败。因为超过了限制的时间

第二个方法exception()中,会抛出一个非受检异常ArithmeticException。而@Test的expected属性中指定了预期异常为ArithmeticException,所以这个方法测试的结果是成功

异常

异常除了使用上面介绍的异常检查之外,还有一种异常检查,该异常除了可以检查异常的类型之外,还可以检查异常的出错信息

这种方法在使用时,需要先声明ExpectedException

@Rule
public ExpectedException thrown= ExpectedException.none();

在写测试代码之前需要一个辅助类,用于抛出异常

public class Student {
  public boolean canVote(int age) {
      if (age<=0) throw new IllegalArgumentException("age should be +ve");
      if (age<18) return false;
      else return true;
  }
}

然后使用如下代码来验证预期的异常

@Test
public void testExpectedException(){
    Student student = new Student();
    thrown.expect(IllegalArgumentException.class);
    thrown.expectMessage("age should be +ve");
    student.canVote(0);
}

只有当异常类型与异常信息完全匹配时,测试才成功

Runner

Runner可以翻译成运行器,JUnit中的代码是由Runner(运行器)来执行的。在JUnit4中默认的Runner是BlockJUnit4ClassRunner取代原来的JUnit4ClassRunner在JUnit中有很多内置的Runner,也有很多第三方的Runner。通过在类上增加注解@RunWith()既可以指定Runner。在指定Runner之后,这些方法就会使用指定的Runner来执行测试方法。

内置的Runner主要有Suite,Parameterized,Categories.
这里介绍一下Suite和Parameterized这两个Runner

Suite

是一个标准Runner,用来批量执行包含在各个类中的测试方法。基于之前的介绍,我们可能有多个JUnit测试类,如果每个测试类都手动去测试的话,比较浪费时间,使用Suite运行器的话,可以将这些测试类整合起来,一次测试所有的测试类。
示例代码:

import org.junit.runner.RunWith;
import org.junit.runners.Suite;

@RunWith(Suite.class)
@Suite.SuiteClasses({
  TestFeatureLogin.class,
  TestFeatureLogout.class,
  TestFeatureNavigate.class,
  TestFeatureUpdate.class
})
public class FeatureTestSuite {
  // 这个类的内容没有任何内容
  //仅仅用来作为一个容器,用于容纳上述所说的测试类。 
}

如上,当运行这类时,会执行Suite.SuiteClasses指定的类中的所有测试方法

Parameterized

是一个实现参数化测试的标准运行器,,当运行参数化测试类时,将创建用于测试方法和测试数据元素的叉积的实例。具体示例如下:
先创建一个测试时候用的计算Fibonacci的类

public class Fibonacci {
    public static int compute(int n) {
        int result = 0;

        if (n <= 1) { 
            result = n; 
        } else { 
            result = compute(n - 1) + compute(n - 2); 
        }
        return result;
    }
}

测试类:

import java.util.Arrays;
import java.util.Collection;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import static org.junit.Assert.*;

@RunWith(Parameterized.class)
public class FibonacciTest {
    @Parameters
    public static Collection<Object[]> data() {
        return Arrays.asList(new Object[][] {     
                 { 0, 0 }, { 1, 1 }, { 2, 1 }, { 3, 2 }, { 4, 3 }, { 5, 5 }, { 6, 8 }  
           });
    }

    private int fInput;

    private int fExpected;

    public FibonacciTest(int input, int expected) {
        fInput= input;
        fExpected= expected;
    }

    @Test
    public void test() {
        assertEquals(fExpected, Fibonacci.compute(fInput));
    }
}

每个FibonacciTest的实例都会使用两个参数的构造器以及使用data中的数据来创建实例,之后来运行测试

除了使用上述方式之外,也可以使用另外一种注解的方式来注入两个字段,如下:

import java.util.Arrays;
import java.util.Collection;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameter;
import org.junit.runners.Parameterized.Parameters;

@RunWith(Parameterized.class)
public class FibonacciTest {
    @Parameters
    public static Collection<Object[]> data() {
        return Arrays.asList(new Object[][] {
                 { 0, 0 }, { 1, 1 }, { 2, 1 }, { 3, 2 }, { 4, 3 }, { 5, 5 }, { 6, 8 }  
           });
    }
    @Parameter // first data value (0) is default
    public /* NOT private */ int fInput;
    @Parameter(value = 1)
    public /* NOT private */ int fExpected;
    @Test
    public void test() {
        assertEquals(fExpected, Fibonacci.compute(fInput));
    }
}

第三方的Runner如下:
- SpringJUnit4ClassRunner:Spring中使用的Runner
- MockitoJUnitRunner:
- HierarchicalContextRunner:
- Avh4’s Nested:
- NitorCreation’s NestedRunner:

实际开发用到的主要是SpringJUnit4ClassRunner,主要介绍一下这个Runner

SpringJUnit4ClassRunner

使用SpringJUnitClassRunner的好处是在对Spring中的Bean进行测试时,不需要去手动创建ApplicationContext,在测试类中也可以使用Spring中的自动注入等功能,以下是一个例子

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import com.tplink.oa.file.softfile.service.ISoftFileTransferService;
import com.tplink.oa.util.dao.GenericDAO;
import static junit.framework.Assert.*;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:applicationContext.xml"})
public class SoftTest {
    @Autowired
    GenericDAO genericDAO;

    @Test
    public void testGenericDAO() throws InterruptedException{
        assertNotNull(genericDAO);
    }
}

在上面的代码中可以看到,只需要配置SpringJUnit4ClassRunner的Runner,并且在测试类上配置@ContextConfiguration就可以自动加载ApplicationContext,并且使用Spring的依赖注入等功能。方便测试

关于JUnit4的更多介绍,可以参考JUnit4的GitHub wiki。

GitHub wiki

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值