JUnit4--- @Annotation注解总结

总结一下JUnit4中常用的注解

1.@RunWith:一个类添加@RunWith或继承的父类添加@RunWith时,JUnit会调用@RunWith使用指定的自定义Runner来执行该类中的测试方法,而不是JUnit4中固定的Runner。

Runner就是用来执行测试用例并通知给RunNotifier执行测试用例的进展。

JUnit4默认的Runner为BlockJUnit4ClassRunner,当你在Eclipse中新建一个JUnit Test Case时,生成的class并未显示指定@RunWith,这时Runner为默认的BlockJUnit4ClassRunner。

java.lang.Object
  org.junit.runner.Runner
      org.junit.runners.ParentRunner<FrameworkMethod>
          org.junit.runners.BlockJUnit4ClassRunner

常见的Runner有4类:

(1).Suite:执行指定多个类的测试方法。

java.lang.Object
  org.junit.runner.Runner
      org.junit.runners.ParentRunner<Runner>
          org.junit.runners.Suite

如下,运行SuiteClassTest,会执行聚合ATest.class和BTest.class中所有的测试方法。

@RunWith(Suite.class)

@SuiteClasses({ATest.class, BTest.class})

public class SuiteClassTest{

}

(2).Parameterized:执行参数化测试。

java.lang.Object
  org.junit.runner.Runner
      org.junit.runners.ParentRunner<Runner>
          org.junit.runners.Suite
              org.junit.runners.Parameterized

(3).Theories:根据@DataPoint作为输入数据,执行测试方法。

java.lang.Object
  org.junit.runner.Runner
      org.junit.runners.ParentRunner<FrameworkMethod>
          org.junit.runners.BlockJUnit4ClassRunner
              org.junit.experimental.theories.Theories

(4).Categories:执行@IncludeCategory或其子类型的测试方法或类。

java.lang.Object
  org.junit.runner.Runner
      org.junit.runners.ParentRunner<Runner>
          org.junit.runners.Suite
              org.junit.experimental.categories.Categories

当然,还可以自定义Runner:

(5)RetryRunner重试机制,淘测试中一篇文章:http://www.taobaotest.com/blogs/2373。

(6)ConcurrentSuite:使用线程池并发执行测试用例,另写文章介绍JUnit4的并发执行。

2.@Test:标记为测试方法。

注解成员有:(1)timeout=100ms,超时验证 (2)expected=异常class,抛出异常验证

3.@Ignore:忽略此测试方法。

4.@BeforeClass,在开始执行整个类的测试方法前,先执行一次该方法。申请资源等。

@AfterClass,在执行完整个类的测试方法后,执行一次该方法。释放资源等。

@Before,在执行整个类的每个测试方法前,执行一次该方法。

@After,在执行完整个类的每个测试方法后,执行一次该方法。

5.@FixMethodOrder,指定测试方法的顺序,

比如:@FixMethodOrder(MethodSorters.NAME_ASCENDING), 以方法名的字典序执行。MethodSortersm枚举类型:

DEFAULT 
          Sorts the test methods in a deterministic, but not predictable, order
JVM 
          Leaves the test methods in the order returned by the JVM.
NAME_ASCENDING 
          Sorts the test methods by the method name, in lexicographic order, with Method.toString() used as a tiebreaker


理论介绍完了,下面用实例来实践下。

1.被测类 Calculator.java

public class Calculator {

	public double add(double num1, double num2) {
		return num1 + num2;
	}

	public double minus(double num1, double num2) {
		return num1 - num2;
	}

	public double multiply(double num1, double num2) {
		// 死循环,模拟超时
		int i = 0;
		while (true) {
			i++;
		}
		
	}

	public double division(double num1, double num2) {
		if(0.0 == num2){
			throw new ArithmeticException("被除数不能为0");
		}else{
			return num1 / num2;
		}
		
	}
}

(一) JUnit测试类  CalculatorTest.java, 用到的注解有:@BeforeClass, @AfterClass, @Before, @After,@Test(timeout, expected元素), @Ignore, @Category

package com.junit.annotest;
import static org.junit.Assert.*;
import static org.hamcrest.Matchers.*;

import java.util.ArrayList;

import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.experimental.categories.Category;


public class CalculatorTest {
	public interface SmokeTests{
		
	}
	
	public interface SlowTests{
		
	}
	
	@BeforeClass
	public static void setUpBeforeClass() throws Exception {
		System.out.println("BeforeClass");
	}

	@AfterClass
	public static void tearDownAfterClass() throws Exception {
		System.out.println("AfterClass");
	}

	@Before
	public void setUp() throws Exception {
		System.out.println("Before");
	}

	@After
	public void tearDown() throws Exception {
		System.out.println("After");
	}

	public CalculatorTest(){
		System.out.println("无参构造函数");
	}
	
	@Category(SmokeTests.class)
	@Test
	public void testAdd1() {
		assertThat(3.64, is(new Calculator().add(3.14, 0.5)));
	}
	
	@Category(SlowTests.class)
	@Test
	public void testAdd2() throws Exception {
		Thread.sleep(1000);
		assertThat(1003.14, is(new Calculator().add(3.14, 1000)));
	}
	
	@Category(SlowTests.class)
	@Test
	public void testAdd3() throws Exception {
		Thread.sleep(2000);
		assertThat(2003.14, is(new Calculator().add(3.14, 2000)));
	}
	
	@Ignore
	@Test
	public void testMinus() {
		assertThat(0.0, is(new Calculator().minus(3.14, 3.14)));
	}
	
	@Test(timeout=1000)
	public void testMultiply()  {
		assertThat(3.14, is(new Calculator().multiply(3.14, 1.0)));
	}
	
	@Test(expected=ArithmeticException.class)
	public void testDivision() {
		new Calculator().division(3.14, 0.0);
	}
	
}

Console下显示如下:可以看到,每次运行测试方法时,都会调用构造函数。

BeforeClass

无参构造函数

Before

After

无参构造函数

Before

After

无参构造函数

Before

After

无参构造函数

Before

After

无参构造函数

Before

After

AfterClass

运行结果如下:

testMultiply测试方法使用了@test(timeout=1000), 如果方法执行时间超过1000ms, 则该测试方法执行为Errors。


JUnit4--- @Annotation注解总结_第1张图片

(二)CategoriesTest.java 使用了Categories Runner,执行分类的用例;@SuiteClasses指定特定的测试类;@IncludeCategory指定执行被标记分类(@Category(标记分类名.class))的测试类或方法。如下,

@IncludeCategory(SmokeTests.class)只运行

CalculatorTest.class中被标记为SmokeTests的测试方法:testAdd1(); @ExcludeCategory 不执行测试类或方法。

package com.junit.annotest;
import static org.junit.Assert.*;

import org.junit.AfterClass;
import org.junit.Test;
import org.junit.experimental.categories.Categories;
import org.junit.experimental.categories.Categories.IncludeCategory;
import org.junit.runner.RunWith;
import org.junit.runners.Suite.SuiteClasses;

import com.junit.annotest.CalculatorTest.SmokeTests;

@RunWith(Categories.class)
@SuiteClasses(CalculatorTest.class)
@IncludeCategory(SmokeTests.class)
public class CategoriesTest {
	
}

运行结果如下:

JUnit4--- @Annotation注解总结_第2张图片


2. Runner: Parameterized,参数化执行用例。

被测类:Fibonacci.java

package com.junit.annotest;

public class Fibonacci {

	// 根据index,获取Fibonacci数列的值
	public int valueOfFib(int index){
		if(0 == index){
			return 0;
		}else if(1 == index){
			return 1;
		}else{
			return valueOfFib(index-2) + valueOfFib(index-1);
		}
	}
}

(一)使用带参构造函数获取数据集

@Parameters指定数据集,该注解下有个name成员,可以标注每个数据集成员的信息,index所在数据集索引,{n}每个数据集元素{...}的第n+1的值。被注解的方法返回数据集数组。运行测试方法时,通过带参构造函数,生成FibonacciTest实例,获取数据集成员,一组数据集对应执行一次。

package com.junit.annotest;

import static org.junit.Assert.*;
import static org.hamcrest.Matchers.*;

import java.util.Arrays;
import java.util.Iterator;
import java.util.List;

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

@RunWith(Parameterized.class)
public class FibonacciTest {

	@Parameters(name="{index}:fib[{0}]={1}")
	public static List<Object[]> data() {
		return Arrays.asList(
				new Object[][] { { 0, 0 }, { 1, 1 }, { 2, 1 }, { 3, 2 },
						{ 4, 3 }, { 5, 5 }, { 8, 21 } });
	}

	private int index;
	private int value;
	
	
	
	public FibonacciTest(int index, int value) {
		super();
		this.index = index;
		this.value = value;
	}



	@Test
	public void testFib() {
		assertThat(value, is(new Fibonacci().valueOfFib(index)));
	}

}
运行结果:

JUnit4--- @Annotation注解总结_第3张图片


(二)使用@Parameter(n)获取数据集

注意,这时类数据成员为public访问类型,并为数据成员指定@parameter(n),n表示该成员获取数据集中元素第n个值。

package com.junit.annotest;

import static org.hamcrest.Matchers.is;
import static org.junit.Assert.*;

import java.util.Arrays;
import java.util.List;

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 FibonacciTest2 {

	@Parameters(name="{index}:fib[{0}]={1}")
	public static List<Object[]> data(){
		return Arrays.asList(new Object[][] { { 0, 0 }, { 1, 1 }, { 2, 1 }, { 3, 2 },
				{ 4, 3 }, { 5, 5 }, { 8, 21 } });
	}
	
	@Parameter(0)
	public int index;
	
	@Parameter(1)
	public int value;
	
	@Test
	public void testFib() {
		assertThat(value, is(new Fibonacci().valueOfFib(index)));
	}
}

运行结果:同上图。

3.Runner: Theories 通过@DataPoint(单个),@DataPoints(数组)指定数据集;@Theory指定测试方法,该方法带形参,获取前面@DataPoint或@DataPoints指定的数据。适合使用大量数据,进行测试。

package com.junit.annotest;

import static org.junit.Assert.*;
import static org.hamcrest.Matchers.*;

import org.junit.Test;
import org.junit.experimental.theories.DataPoint;
import org.junit.experimental.theories.DataPoints;
import org.junit.experimental.theories.Theories;
import org.junit.experimental.theories.Theory;
import org.junit.runner.RunWith;

@RunWith(Theories.class)
public class TheoriesTest {

	@DataPoint
	public static int num1 = 2;
	
	@DataPoint
	public static int num2 = 8;
	
	@DataPoints
	public static int[] num3 = {4, 5, 6, 7, 9};
	
	
	@Theory
	public void testFibon(int num) {
		System.out.println(num);
		assertThat(num,greaterThan(0));
	}

}
测试结果如下:

JUnit4--- @Annotation注解总结_第4张图片



你可能感兴趣的:(测试,JUnit)