代码之家  ›  专栏  ›  技术社区  ›  Stefan Sveidqvist

反复运行同一个junit测试的简单方法?

  •  89
  • Stefan Sveidqvist  · 技术社区  · 17 年前

    例如,连续10次运行同一测试并报告结果。

    理想的解决方案是我不知道的Eclipse插件/设置/特性。

    11 回复  |  直到 17 年前
        1
  •  133
  •   Stefan Birkner    8 年前

    实现这一点的最简单方法(所需的新代码量最少)是将测试作为参数化测试运行(使用 @RunWith(Parameterized.class)

    该测试需要是类中唯一的测试,或者更好地说,所有测试方法都需要在类中运行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");
        }
    }
    

    有了上面的内容,甚至可以使用无参数构造函数来实现,但我不确定框架作者是否有意这样做,或者这在将来是否会中断。

    如果您正在实现自己的runner,那么您可以让runner运行测试10次。如果您使用的是第三方runner,那么在4.7中,您可以使用新的 @Rule MethodRule 接口,以便它接受该语句并在for循环中执行10次。目前这种方法的缺点是 @Before 和 @After @以前 将在 ),但无论如何,您将在对象的同一实例上执行操作(对于 Parameterized 跑步者)。这假设运行该类的任何运行程序都能正确识别 @统治 注释。只有授权给JUnit跑步者时才是这样。

    如果您使用的自定义运行程序无法识别 @统治 注释,那么您就必须编写自己的运行程序,适当地委托给该运行程序并运行10次。

    请注意,还有其他可能解决此问题的方法(如Theory runner),但它们都需要一个runner。不幸的是,JUnit目前不支持跑步者层。那是一个束缚其他跑步者的跑步者。

        2
  •  112
  •   smac89    9 年前

    使用IntelliJ,您可以从测试配置中执行此操作。打开此窗口后,可以选择运行测试任意次数,。

    enter image description here

    运行测试时,intellij将按照指定的次数执行您选择的所有测试。

    enter image description here

        3
  •  69
  •   David Tonhofer    9 年前

    我发现Spring的repeat注释对这类事情很有用:

    @Repeat(value = 10)
    

    最新(Spring Framework 4.3.11.API发布版)文档:

        4
  •  50
  •   César Alberca    9 年前

    有了JUnit5,我可以使用 @RepeatedTest 注释:

    @RepeatedTest(10)
    public void testMyCode() {
        //your test code goes here
    }
    

    注意 @Test @RepeatedTest .

        5
  •  36
  •   Dave Jarvis James Eichele    6 年前

    受以下资源启发:

    实例

    创建并使用 @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;
        }
    }
    

    PowerMock

    将此解决方案用于 @RunWith(PowerMockRunner.class) ,需要更新到 Powermock 1.6.5 (其中包括 a patch ).

        6
  •  13
  •   Dmitry Ginzburg    11 年前

    有什么问题吗

    @Test
    void itWorks() {
        // stuff
    }
    
    @Test
    void itWorksRepeatably() {
        for (int i = 0; i < 10; i++) {
            itWorks();
        }
    }
    

    与测试每个值数组的情况不同,您并不特别关心哪个运行失败。

        7
  •  7
  •   Qualk    14 年前

    这对我来说容易多了。

    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;
        }
    }
    
        8
  •  7
  •   Andrii Abramov Mk.Sl.    9 年前

    tempus-fugit 使用JUnit4.7的库 @Rule 重复测试多次或多次重复测试 @RunWith .

    例如

    @RunWith(IntermittentTestRunner.class)
    public class IntermittentTestRunnerTest {
    
       private static int testCounter = 0;
    
       @Test
       @Intermittent(repition = 99)
       public void annotatedTest() {
          testCounter++;
       }
    }
    

    测试运行后(间歇性TestRunner处于 @RunWith ), testCounter

        9
  •  1
  •   bob    7 年前

    这基本上是Yishai在上面提供的答案,用Kotlin重新编写:

    @RunWith(Parameterized::class)
    class MyTest {
    
        companion object {
    
            private const val numberOfTests = 200
    
            @JvmStatic
            @Parameterized.Parameters
            fun data(): Array<Array<Any?>> = Array(numberOfTests) { arrayOfNulls<Any?>(0) }
        }
    
        @Test
        fun testSomething() { }
    }
    
        10
  •  1
  •   Mehraj Malik    6 年前

    在里面 JUnit 5 通过使用 @RepeatedTest

    @RepeatedTest用于表示带注释的方法是测试 应重复指定次数的模板方法。

        @RepeatedTest(3) // Runs N Times
        public void test_Prime() {
        }
    

    www.baeldung.com

        11
  •  0
  •   Anderson Marques    9 年前

    我构建了一个模块,允许进行此类测试。但它不仅关注重复。但是为了保证某些代码是线程安全的。

    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");
        }
    }
    

    这是一个开源项目。随时改进。

        12
  •  0
  •   silver_mx    9 年前

    您可以从主方法运行JUnit测试,并根据需要重复多次:

    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
    
                }
            }
    
        }
    
    }