简单的方法一遍又一遍地运行相同的junittesting?
就像标题所说,我正在寻找一些简单的方法来使用Eclipse自动运行几次JUnit 4.xtesting。
一个例子是连续运行相同的testing10次并报告结果。
我们已经有了这样一个复杂的方法,但是我正在寻找一个简单的方法来做到这一点,这样我就可以确定我一直试图解决的片状testing保持不变。
一个理想的解决scheme将是我不知道的Eclipse插件/设置/function。
要做到这一点,最简单的方法就是作为参数化testing运行testing(用@RunWith(Parameterized.class)
注释并添加一个方法来提供10个空参数)。 这样框架将运行testing10次。
这个testing将需要在课堂上唯一的testing,或者更好地把所有的testing方法都需要在课堂上运行10次。
这里是一个例子:
@RunWith(Parameterized.class) public class RunTenTimes { @Parameterized.Parameters public static List<Object[]> data() { return Arrays.asList(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
之后运行),但不pipe你是否在同一个对象实例上(不是Parameterized
runner)。 这假设无论您是否正在运行类的运行程序, @Rule
正确识别@Rule
注释。 只有在委托给JUnit运动员的情况下才是这种情况。
如果你正在运行一个不能识别@Rule
注解的自定义运行器,那么你真的不得不编写你自己的runner来适当地委托给那个Runner并运行它10次。
请注意,还有其他方法可以解决这个问题(如Theories跑步者),但他们都需要跑步者。 不幸的是,JUnit目前不支持多层跑步者。 这是一个连锁其他跑步者的跑步者。
我发现Spring的重复注释对于这样的事情是有用的:
@Repeat(value = 10)
最新(Spring Framework 4.3.11.RELEASE API)doc:
- org.springframework.test.annotation
- 春季unit testing
启发了这个解决scheme :
像这样使用@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)
时使用此解决scheme,更新到Powermock 1.6.5 ( 其中包括此修补程序 )。
任何错误的:
@Test void itWorks() { // stuff } @Test void itWorksRepeatably() { for (int i = 0; i < 10; i++) { itWorks(); } }
与testing每个值的数组不同的是,您并不特别关心哪个运行失败。
无需在configuration或注释中执行代码中的操作。
这对我来说更容易。
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; } }
tempus-fugit库中有一个间断注释,它可以和JUnit 4.7的@Rule
一起重复testing几次或使用@RunWith
。
例如,
@RunWith(IntermittentTestRunner.class) public class IntermittentTestRunnerTest { private static int testCounter = 0; @Test @Intermittent(repition = 99) public void annotatedTest() { testCounter++; } }
运行testing之后(使用@RunWith
中的@RunWith
), testCounter
将等于99。
使用JUnit 5,我可以使用@RepeatedTest注解来解决这个问题:
@RepeatedTest(10) public void testMyCode() { //your test code goes here }
请注意@Test
注释不应该与@RepeatedTest
一起使用。
使用IntelliJ,您可以从testingconfiguration中执行此操作。 一旦你打开这个窗口,你可以select任何你想要的次数运行testing。
当你运行testing时,intellij会执行你select的所有testing次数。
运行624个testing的例子10次:
我build立一个允许做这种testing的模块。 但它不仅仅是重复。 但是保证一些代码是线程安全的。
https://github.com/anderson-marques/concurrent-testing
Maven依赖:
<dependency> <groupId>org.lite</groupId> <artifactId>concurrent-testing</artifactId> <version>1.0.0</version> </dependency>
使用示例:
package org.lite.concurrent.testing; import org.junit.Assert; import org.junit.Rule; import org.junit.Test; import ConcurrentTest; import ConcurrentTestsRule; /** * Concurrent tests examples */ public class ExampleTest { /** * Create a new TestRule that will be applied to all tests */ @Rule public ConcurrentTestsRule ct = ConcurrentTestsRule.silentTests(); /** * Tests using 10 threads and make 20 requests. This means until 10 simultaneous requests. */ @Test @ConcurrentTest(requests = 20, threads = 10) public void testConcurrentExecutionSuccess(){ Assert.assertTrue(true); } /** * Tests using 10 threads and make 20 requests. This means until 10 simultaneous requests. */ @Test @ConcurrentTest(requests = 200, threads = 10, timeoutMillis = 100) public void testConcurrentExecutionSuccessWaitOnly100Millissecond(){ } @Test(expected = RuntimeException.class) @ConcurrentTest(requests = 3) public void testConcurrentExecutionFail(){ throw new RuntimeException("Fail"); } }
这是一个开源项目。 随意改善。
你可以从一个主要的方法运行你的JUnittesting,并重复这么多次你需要:
package tests; import static org.junit.Assert.*; import org.junit.Test; import org.junit.runner.Result; public class RepeatedTest { @Test public void test() { fail("Not yet implemented"); } public static void main(String args[]) { boolean runForever = true; while (runForever) { Result result = org.junit.runner.JUnitCore.runClasses(RepeatedTest.class); if (result.getFailureCount() > 0) { runForever = false; //Do something with the result object } } } }