就像标题所说,我正在寻找一些使用Eclipse自动连续多次运行JUnit 4.x测试的简单方法.
一个例子是连续10次运行相同的测试并报告结果.
我们已经有了一个复杂的方法来做这个,但我正在寻找一种简单的方法来做到这一点,以便我可以确定我一直试图修复的片状测试保持固定.
一个理想的解决方案是我不知道的Eclipse插件/设置/功能.
最简单的(至少需要新代码量)方法是将测试作为参数化测试运行(使用an注释@RunWith(Parameterized.class)
并添加方法以提供10个空参数).这样,框架将运行测试10次.
这个测试需要是该类中唯一的测试,或者更好的是所有测试方法都需要在类中运行10次.
这是一个例子:
@RunWith(Parameterized.class) public class RunTenTimes { @Parameterized.Parameters public static Object[][] data() { return new Object[10][0]; } public RunTenTimes() { } @Test public void runsTenTimes() { System.out.println("run"); } }
有了上述内容,甚至可以使用无参数构造函数来完成它,但我不确定框架作者是否打算这样做,或者将来是否会破坏.
如果您正在实施自己的跑步者,那么您可以让跑步者进行10次测试.如果您正在使用第三方运行程序,那么使用4.7,您可以使用新@Rule
注释并实现MethodRule
接口,以便它接受语句并在for循环中执行10次.这种方法的当前缺点是@Before
并@After
获得只运行一次.这可能会在JUnit的下一个版本(@Before
将在之后运行@Rule
)中发生变化,但是无论你是在同一个对象实例上行动(对于Parameterized
跑步者来说都不是这样).这假设您正在运行该类的任何跑步者正确识别@Rule
注释.只有当它委托给JUnit运行者时才会这样.
如果您使用的是不能识别@Rule
注释的自定义运行器,那么您真的不得不编写自己的运行器,该运行器适当地委派给Runner并运行10次.
请注意,还有其他方法可以解决这个问题(例如Theories runner),但它们都需要跑步者.不幸的是,JUnit目前不支持跑步者层.这是一个连锁其他选手的跑步者.
使用IntelliJ,您可以从测试配置中执行此操作.打开此窗口后,您可以选择任意次数运行测试.
当您运行测试时,intellij将按您指定的次数执行您选择的所有测试.
示例运行624次测试10次:
我发现Spring的重复注释对于这种事情很有用:
@Repeat(value = 10)
最新(Spring Framework 4.3.11.RELEASE API)doc:
org.springframework.test.annotation
春季单元测试
灵感来自这个解决方案:
使用这样的@Repeat
注释:
public class MyTestClass {
@Rule
public RepeatRule repeatRule = new RepeatRule();
@Test
@Repeat(10)
public void testMyCode() {
//your test code goes here
}
}
你只需要这两个类:
Repeat.java:
import static java.lang.annotation.ElementType.ANNOTATION_TYPE;
import static java.lang.annotation.ElementType.METHOD;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
@Retention( RetentionPolicy.RUNTIME )
@Target({ METHOD, ANNOTATION_TYPE })
public @interface Repeat {
int value() default 1;
}
RepeatRule.java:
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
public class RepeatRule implements TestRule {
private static class RepeatStatement extends Statement {
private final Statement statement;
private final int repeat;
public RepeatStatement(Statement statement, int repeat) {
this.statement = statement;
this.repeat = repeat;
}
@Override
public void evaluate() throws Throwable {
for (int i = 0; i < repeat; i++) {
statement.evaluate();
}
}
}
@Override
public Statement apply(Statement statement, Description description) {
Statement result = statement;
Repeat repeat = description.getAnnotation(Repeat.class);
if (repeat != null) {
int times = repeat.value();
result = new RepeatStatement(statement, times);
}
return result;
}
}
2016-10-25编辑:
为了在使用时使用此解决方案@RunWith(PowerMockRunner.class)
,请更新到Powermock 1.6.5(包括此补丁).
使用JUnit 5,我能够使用@RepeatedTest注释解决这个问题:
@RepeatedTest(10) public void testMyCode() { //your test code goes here }
请注意,@Test
注释不应与之一起使用@RepeatedTest
.
有什么不妥:
@Test void itWorks() { // stuff } @Test void itWorksRepeatably() { for (int i = 0; i < 10; i++) { itWorks(); } }
与测试每个值数组的情况不同,您并不特别关心哪个运行失败.
无需在配置或注释中执行代码中的操作.
在tempus-fugit库中有一个Intermittent注释,它与JUnit 4.7 @Rule
一起重复测试几次或使用@RunWith
.
例如,
@RunWith(IntermittentTestRunner.class) public class IntermittentTestRunnerTest { private static int testCounter = 0; @Test @Intermittent(repition = 99) public void annotatedTest() { testCounter++; } }
运行测试后(使用IntermittentTestRunner @RunWith
),testCounter
将等于99.
这对我来说更容易.
public class RepeatTests extends TestCase { public static Test suite() { TestSuite suite = new TestSuite(RepeatTests.class.getName()); for (int i = 0; i < 10; i++) { suite.addTestSuite(YourTest.class); } return suite; } }