JUnit(二)高级之运行器_MD

来源:互联网 发布:word2010表格数据求和 编辑:程序博客网 时间:2024/06/07 23:23

一、概述

当一个类被@RunWith注释或拓展了一个@RunWith注释的类,JUnit将会使用引用的类来执行测试,而不是使用JUnit内置的运行器。

  • The default runner is BlockJUnit4ClassRunner which supersedes[取代] the older JUnit4ClassRunner
  • Annotating a class with @RunWith(JUnit4.class) will always invoke the default JUnit 4 runner in the current version of JUnit, this class aliases the current default JUnit 4 class runner.

Specialized Runners

  • Suite:Suite[测试集]是一个标准的运行器允许你手动构件包含来自许多类的测试集。
  • Parameterized:Parameterized[参数化]是一个标准的运行器 来实现参数化测试。运行参数化测试类时,instances are created for the cross-product of the test methods and the test data elements.
  • Categories:你可以使用Categories运行器来制定一组测试被包含或排除。

Third Party Runners:

  • SpringJUnit4ClassRunner
  • MockitoJUnitRunner
  • HierarchicalContextRunner
  • Avh4’s Nested
  • NitorCreation’s NestedRunner

二、Aggregating[集成] tests in suites

使用Suite运行器允许你手动创建一个包含多个类的测试集。使用@RunWith(Suite.class)@SuiteClasses(TestClass1.class, ...)来注释类。然后你可以运行这个类,其会运行 @SuiteClasses 中指定的所有类。

示例

@RunWith 注解指定使用 org.junit.runners.Suite 运行器进行运行测试类。@Suite.SuiteClasses 告诉测试运行器 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 {  // the class remains empty,  // used only as a holder for the above annotations}

注意:我们可以直接使用 @SuiteClasses 注解来取代 @Suite.SuiteClasses 注解。

三、Parameterized[参数] tests

The custom runner Parameterized implements parameterized tests. When running a parameterized test class,

定制的Parameterized运行器实现了参数化测试。运行参数化测试类时,instances are created for the cross-product of the test methods and the test data elements.

例如,我们来测试一个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 static org.junit.Assert.assertEquals;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;@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实例使用两个参数进行构造,而数据值来自@Parameters指定的方法。

使用@Parameter进行字段注入来取代构造器

It is also possible to inject data values directly into fields without needing a constructor using the @Parameter annotation, like so:

也可以使用@Parameter注解将数据值直接注入到字段中,而不需要构造函数,示例如下:

import static org.junit.Assert.assertEquals;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(1)    public /* NOT private */ int fExpected;    @Test    public void test() {        assertEquals(fExpected, Fibonacci.compute(fInput));    }}public class Fibonacci {    ...}

Tests with single parameter

(Since 4.12-beta-3)

If your test needs a single parameter only, you don’t have to wrap it with an array. Instead you can provide an Iterable or an array of objects.

@Parameterspublic static Iterable<? extends Object> data() {    return Arrays.asList("first test", "second test");}

@Parameterspublic static Object[] data() {    return new Object[] { "first test", "second test" };}

Identify Individual test cases

In order to easily identify the individual test cases in a Parameterized test, you may provide a name using the @Parameters annotation. This name is allowed to contain placeholders that are replaced at runtime:

  • {index}: the current parameter index
  • {0}, {1}, …: the first, second, and so on, parameter value. NOTE: single quotes ’ should be escaped as two single quotes ''.

示例:

import static org.junit.Assert.assertEquals;import java.util.Arrays;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 Iterable<Object[]> data() {        return Arrays.asList(new Object[][] {                 { 0, 0 }, { 1, 1 }, { 2, 1 }, { 3, 2 }, { 4, 3 }, { 5, 5 }, { 6, 8 }           });    }    private int input;    private int expected;    public FibonacciTest(int input, int expected) {        this.input = input;        this.expected = expected;    }    @Test    public void test() {        assertEquals(expected, Fibonacci.compute(input));    }}public class Fibonacci {    ...}

In the example given above, the Parameterized runner creates names like [1: fib(3)=2]. If you don’t specify a name, the current parameter index will be used by default.

赞赏码