JUnit4--- @Annotation注解总结

来源:互联网 发布:类似instagram的软件 编辑:程序博客网 时间:2024/05/06 01:50

总结一下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  extended by org.junit.runner.Runner      extended by org.junit.runners.ParentRunner<FrameworkMethod>          extended by org.junit.runners.BlockJUnit4ClassRunner

常见的Runner有4类:

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

java.lang.Object  extended by org.junit.runner.Runner      extended by org.junit.runners.ParentRunner<Runner>          extended by 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  extended by org.junit.runner.Runner      extended by org.junit.runners.ParentRunner<Runner>          extended by org.junit.runners.Suite              extended by org.junit.runners.Parameterized

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

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

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

java.lang.Object  extended by org.junit.runner.Runner      extended by org.junit.runners.ParentRunner<Runner>          extended by org.junit.runners.Suite              extended by 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, orderJVM 
          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{}@BeforeClasspublic static void setUpBeforeClass() throws Exception {System.out.println("BeforeClass");}@AfterClasspublic static void tearDownAfterClass() throws Exception {System.out.println("AfterClass");}@Beforepublic void setUp() throws Exception {System.out.println("Before");}@Afterpublic void tearDown() throws Exception {System.out.println("After");}public CalculatorTest(){System.out.println("无参构造函数");}@Category(SmokeTests.class)@Testpublic void testAdd1() {assertThat(3.64, is(new Calculator().add(3.14, 0.5)));}@Category(SlowTests.class)@Testpublic void testAdd2() throws Exception {Thread.sleep(1000);assertThat(1003.14, is(new Calculator().add(3.14, 1000)));}@Category(SlowTests.class)@Testpublic void testAdd3() throws Exception {Thread.sleep(2000);assertThat(2003.14, is(new Calculator().add(3.14, 2000)));}@Ignore@Testpublic 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。



(二)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 {}

运行结果如下:



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;}@Testpublic void testFib() {assertThat(value, is(new Fibonacci().valueOfFib(index)));}}
运行结果:



(二)使用@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;@Testpublic 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 {@DataPointpublic static int num1 = 2;@DataPointpublic static int num2 = 8;@DataPointspublic static int[] num3 = {4, 5, 6, 7, 9};@Theorypublic void testFibon(int num) {System.out.println(num);assertThat(num,greaterThan(0));}}
测试结果如下:





0 0