文章目录
  1. 1. 问题
  2. 2. 解答
  3. 3. 参考

问题

如何运行一个测试用例多次?

解答

  1. 使用@RunWith(Parameterized.class),需要多写一些无谓的代码
  2. 使用Rule,自己实现Repeat注解.见[参考4][4]
  3. 使用Runner,自己实现Repeat注解.见参考1 这个方法目前实验起来最好。
    使用:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    @RunWith(ExtendedRunner.class)  
    public class ExampleTest3 {
    @Test
    @Repeat(10)
    public void sometimesFail() {
    int rand = new Random().nextInt(3);
    if (rand % 3 == 0) {
    fail();
    }
    }
    }

Repeat.java:

1
2
3
4
5
@Retention(RetentionPolicy.RUNTIME)  
@Target({ElementType.METHOD})
public @interface Repeat {
int value();
}

ExtendedRunner.java:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
public class ExtendedRunner extends BlockJUnit4ClassRunner {  
public ExtendedRunner(Class<?> klass) throws InitializationError {
super(klass);
}

@Override
protected Description describeChild(FrameworkMethod method) {
if (method.getAnnotation(Repeat.class) != null &&
method.getAnnotation(Ignore.class) == null) {
return describeRepeatTest(method);
}
return super.describeChild(method);
}

private Description describeRepeatTest(FrameworkMethod method) {
int times = method.getAnnotation(Repeat.class).value();

Description description = Description.createSuiteDescription(
testName(method) + " [" + times + " times]",
method.getAnnotations());

for (int i = 1; i <= times; i++) {
description.addChild(Description.createTestDescription(
getTestClass().getJavaClass(),
"[" + i + "] " + testName(method)));
}
return description;
}

@Override
protected void runChild(final FrameworkMethod method, RunNotifier notifier) {
Description description = describeChild(method);

if (method.getAnnotation(Repeat.class) != null &&
method.getAnnotation(Ignore.class) == null) {
runRepeatedly(methodBlock(method), description, notifier);
}
super.runChild(method, notifier);
}

private void runRepeatedly(Statement statement, Description description,
RunNotifier notifier) {
for (Description desc : description.getChildren()) {
runLeaf(statement, desc, notifier);
}
}

}

  1. 如果使用了Spring框架,则可以使用注解@Repeat(value = 10)
  2. 另外写一个运行多次的用例,代码如下。多个用例被当成了一个用例。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    @Test
    void itWorks() {
    // stuff
    }

    @Test
    void itWorksRepeatably() {
    for (int i = 0; i < 10; i++) {
    itWorks();
    }
    }
  3. 使用tempus-fugit 库,代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    @RunWith(IntermittentTestRunner.class)
    public class IntermittentTestRunnerTest {

    private static int testCounter = 0;

    @Test
    @Intermittent(repition = 99)
    public void annotatedTest() {
    testCounter++;
    }
    }
  4. 使用easytest-core 库,代码如下。见[参考3][3]

    1
    2
    3
    4
    5
    6
    7
    @Test
    @Repeat(times=20)
    public void testLookup(){
    int[] arr = {2,4,3,4,2,3,3};
    int i = lookupNumber(arr);
    assertEquals(3, i);
    }

参考

[2]:  http://stackoverflow.com/questions/1492856/easy-way-of-running-the-same-junit-test-over-and-over
[3]: http://www.javacodegeeks.com/2013/10/write-effective-load-tests-using-junit-and-repeat-annotation.html
[4]: http://www.codeaffine.com/2013/04/10/running-junit-tests-repeatedly-without-loops/

文章目录
  1. 1. 问题
  2. 2. 解答
  3. 3. 参考