2016-02-11 148 views
3

是否可以使用JUnitCore API运行参数化测试类?使用JUnitCore运行参数化测试

我已经在测试一个类中调用斐波纳契,称为TestFibonacci一个参数测试类,和一个简单的Java类(JUnitParameterized),它执行使用JUnitCore API的TestFibonacci类。如果我使用JUnit插件或命令行执行TestFibonacci,它会通过。但是,当我使用我的JUnitParameterized类执行它时,它会失败。

类被测

public class Fibonacci { 

    public static int compute(int n) { 
    if (n <= 1) { 
     return n; 
    } 
    return compute(n-1) + compute(n-2); 
    } 
} 

测试类

import static org.junit.Assert.assertEquals; 

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

import java.util.Arrays; 

@RunWith(Parameterized.class) 
public class TestFibonacci { 

    @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 TestFibonacci(int input, int expected) { 
    this.input = input; 
    this.expected = expected; 
    } 

    @Test 
    public void test() { 
    assertEquals(expected, Fibonacci.compute(input)); 
    } 
} 

Java程序

import org.junit.runner.JUnitCore; 
import org.junit.runner.Request; 
import org.junit.runner.Result; 

public class JUnitParameterized { 

    public static void main(String[] args) throws ClassNotFoundException { 

    Class<?> testClass = JUnitParameterized.class.getClassLoader().loadClass(TestFibonacci.class.getCanonicalName()); 

    Result result = (new JUnitCore()).run(Request.method(testClass, "test")); 
    System.out.println("Number of tests run: " + result.getRunCount()); 
    System.out.println("The number of tests that failed during the run: " + result.getFailureCount()); 
    System.out.println("The number of milliseconds it took to run the entire suite to run: " + result.getRunTime()); 
    System.out.println("" + (result.wasSuccessful() == true ? "Passed :)" : "Failed :(")); 
    } 
} 

回答

2

当JUnit测试类标注有@Parameterized,该测试方法的名称作为描述是用大括号,冒号和取代的富含数字10你在@Parameters注释中提供。

在你的情况下,执行单一的测试,利用设定一个参数,你会

Result result = (new JUnitCore()).run(Request.method(TestFibonacci.class, "test[6: fib(6)=8]")); 

在这种情况下,第6组参数提供(从零开始)。
请注意,您必须将您在方法名称中提供的数字与声明为参数的数字完全匹配。序列号也很重要。因此以下是行不通的:

"test[3: fib(6)=8]" (wrong sequence .. <6, 8> pair is 6th, not 3rd) 
"test[6: fib(50)=100]" (the pair <50, 100> is not declared in parameters) 

为了避免@Parameters(name=?)值的不必要的解析,我建议只需要声明的参数没有name

@Parameters // no name=? 
public static Iterable<Object[]> data() { 
    return Arrays.asList(
     new Object[][] { { 0, 0 }, { 1, 1 }, { 2, 1 }, { 3, 2 }, { 4, 3 }, { 5, 5 }, { 6, 8 } }); 
} 

然后测试方法的描述仅仅是test[6]

Result result = (new JUnitCore()).run(Request.method(TestFibonacci.class, "test[6]")); 

与所有的参数运行一个测试方法,我会建议做一个周期(一个d可能汇总结果):

int parametersCount = Request.aClass(TestFibonacci.class).getRunner().getDescription().getChildren().size(); 
for (int i = 0; i < parametersCount; ++i) { 
    Result result = (new JUnitCore()).run(Request.method(testClass, "testFloat[" + i + "]")); 
    System.out.println("Result " + result.wasSuccessful()); 
} 
+0

非常感谢斯捷潘。 :) – josecampos