参考:http://blog.youkuaiyun.com/wangjunjun2008/article/details/17242749
http://blog.youkuaiyun.com/wangjunjun2008/article/details/17242749
http://tonl.iteye.com/blog/1948869
http://my.oschina.net/pangyangyang/blog/144495
JUnit核心-测试类,测试集,测试运行器
Junit 4 是与Junit 3 完全不同的API ,它基于Java 5.0 的注解,静态导入构建而成。并且引入了限时,参数化测试用例。
JUnit 中的几个定义:
- TestCase:测试用例,包含一个或者多个测试的类,即包含@Test注解的类
- TestSuit :测试集。 将多个测试归入一组
- TestRunner:测试运行器,执行测试。
- assert:断言
- test:测试
一个计算加减乘除的例子:
public class Calculate {
public int add(int a,int b){
return a+b;
}
public int minus(int a,int b){
return a-b;
}
//错误
public int divide(int a,int b){
return a/b;
}
public int multi(int a, int b){
return a*b;
}
//死循环
public void squart(){
while(true);
}
}
单元测试类
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.After;
//静态导入
import static org.junit.Assert.*;
public class TestCalculate {
private Calculate cal = new Calculate();
public TestCalculate() {
System.out.println("TestCaculate 初始化");
}
@BeforeClass //这里必须是static ,因为是在初始化之前执行的
public static void before(){
System.out.println("测试之前");
}
@Before //执行任何方法之前都会执行setUp
public void setUp(){
System.out.println("一个测试开始");
}
@Test //@Test表示是一个单元测试
public void testAdd(){
/*
* 通过断言来判断
* Junit4 中提供了Assert 类,有大量的断言方法
* 上面将它静态引入,可以直接使用Assert中的静态方法
* AssertEquals,AssertNull,AssertTrue
* */
assertEquals(12,cal.add(4,8));
}
@Test
public void testDivide(){
assertTrue(cal.divide(1, 2)==0);
}
@Test
@Ignore
public void testMulti(){
assertEquals(cal.multi(1, 2),2);
}
@Test(timeout=1000)
public void tetsSquart(){
cal.squart();
}
@After
public void after(){
System.out.println("一个测试结束");
}
}
测试结果:
有一个@Ignore 该测试被忽略,一个死循环的用例,超过了设置的时间限制,测试不通过。
控制台输出:
1,关于注解
根据控制台的输出可以看到,下面注解执行的时间
- BeforeClass ,类方法,类加载时执行。如果测试用例执行前需要一些高开销的资源(连接数据库),可以用@BeforeClass 执行。
- AfterClass ,类方法,整个类结束前执行一次。可以用于资源的释放。
- Before,每个测试用例执行时都会执行,After同理。
- Test,该方法是一个测试方法
- @Test(timeout=##),时间单位是毫秒。
- 关于构造器,在输出中可以看到,每个测试用例都会重新创建一个实例。
2,测试运行器 Runner
Runner 是一个抽象类,用于运行测试和通知Notifier 运行的结果。
JUnit 使用 @RunWith 注解来标注选用的Runner,实现不同的测试行为。
下面是几种TestRunner
- Suite 包含若干个测试类的集合
@RunWith(value = Suite.class)
@SuiteClasses(value={TestCalculate.class,Test1.class})
class TestAll{
}
@SuiteClasses(value={TestCalculate.class,Test1.class}) 声明该测试集所包含的测试类。
- Parameterized 参数化Runner。允许使用不同的参数运行同一个测试。
比如测试 TestDivede 方法,可以使用(1,2),(1,0)(0,1)几组来进行测试。
import static org.junit.Assert.assertEquals;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
@RunWith(value=Parameterized.class)
public class ParamTest{
private Calculate cal =null;
//1,定义测试参数
private int expected;
private int v1;
private int v2;
//2,构造方法
public ParamTest(int expected,int v1,int v2){
this.expected=expected;
this.v1=v1;
this.v2=v2;
}
//3,创建返回参数的静态方法
@Parameters
public static Collection<Integer[]> getParam(){
List<Integer[]> list = new ArrayList<Integer[]>();
list.add(new Integer[]{0,1,0});
list.add(new Integer[]{0,0,1});
list.add(new Integer[]{0,1,2});
return list;
}
@Before
public void setUp(){
cal = new Calculate();
}
@Test
public void TestDiv(){
int res = cal.divide(v1, v2);
assertEquals(res,expected);
}
}
输出:
使用Parameterized 时,需要注意,
- 测试参数需要提前声明
- 构造方法
- 创建一个静态方法,返回类型为
Collection<Integer[]>
,并且该方法加以@Parameters注解(List继承Collection 返回类型根据下面的写成相应的即可,这里可以是List<Integer[]>
)