source

같은 junit 테스트를 몇 번이고 실행할 수 있는 쉬운 방법?

goodcode 2022. 9. 12. 11:39
반응형

같은 junit 테스트를 몇 번이고 실행할 수 있는 쉬운 방법?

제목처럼 Eclipse를 사용하여 JUnit 4.x 테스트를 자동으로 여러 번 실행할 수 있는 간단한 방법을 찾고 있습니다.

예를 들어 같은 테스트를 10회 연속으로 실행하여 결과를 보고하는 경우가 있습니다.

이 작업은 이미 복잡한 방법이 있습니다만, 저는 간단한 방법을 찾고 있습니다.이를 통해 제가 고치려고 했던 불량 테스트를 확실하게 고정시킬 수 있도록 하기 위해서입니다.

이상적 솔루션은 이클립스 플러그인/설정/기능을 인식하지 못하는 것입니다.

이를 위한 가장 쉬운 방법(최소한의 새 코드 필요량만큼)은 테스트를 매개 변수화된 테스트로 실행하는 것입니다(Notate with the parameterized test:@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회 테스트를 실행시킬 수 있습니다.서드파티제의 Runner를 사용하고 있는 경우는, 4.7에서는, 새로운 Runner를 사용할 수 있습니다.@Rule주석 달기 및 구현MethodRulefor 루프에서 스테이트먼트를 10회 실행하도록 인터페이스를 설정합니다.이 접근법의 현재 단점은 다음과 같습니다.@Before그리고.@After한 번만 실행되다이는 JUnit의 다음 버전에서 변경될 수 있습니다.@Before를 쫓다@Rule). 단, 어떤 경우에도 오브젝트의 동일한 인스턴스(에 해당되지 않는 것)에 대해 처리하게 됩니다.Parameterized런너)이것은 클래스를 실행하고 있는 어떤 러너라도 올바르게 인식하고 있는 것을 전제로 하고 있습니다.@Rule주석입니다.그것은 JUnit 주자들에게 위임하는 경우에만 해당된다.

를 인식하지 않는 커스텀러너로 실행하고 있는 경우@Rule주석을 달면 해당 주자에게 적절히 위임하고 10회 실행하는 주자를 직접 작성해야 합니다.

이 문제를 해결할 수 있는 다른 방법(예를 들어 Theons 러너)이 있지만 모두 러너가 필요합니다.안타깝게도 JUnit은 현재 주자 계층을 지원하지 않습니다.그것은 다른 주자를 묶는 주자입니다.

IntelliJ 에서는, 테스트 설정으로부터 이것을 실행할 수 있습니다.이 창을 열면 원하는 횟수만큼 테스트를 실행할 수 있습니다.

여기에 이미지 설명 입력

테스트를 실행하면 지정한 횟수만큼 선택한 모든 테스트가 실행됩니다.

624 테스트를 10회 실행하는 예:

나는 스프링의 반복 주석이 그런 종류의 일에 유용하다는 것을 알았다.

@Repeat(value = 10)

최신(Spring Framework 4.3.11).릴리스 API) 문서:

JUnit 5에서는 @Repeated를 사용하여 이 문제를 해결할 수 있었습니다.테스트 주석:

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

:@Test은 같이 안 요.@RepeatedTest.

다음 리소스에서 영감을 얻습니다.

" " " 를 하여 합니다.@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(패치 포함)로 업데이트해야 합니다.

에 문제가 있는 경우:

@Test
void itWorks() {
    // stuff
}

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

각 값 배열을 테스트하는 경우와 달리 실패한 실행은 특별히 중요하지 않습니다.

코드에서 할 수 있는 작업은 구성 또는 주석에서 수행할 필요가 없습니다.

저는 이게 훨씬 편해요.

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

JUnit 4.7과 연동되는 Tempus-fugit 라이브러리에는 간헐적인 주석이 있습니다.@Rule를 번 @RunWith.

예를들면,

@RunWith(IntermittentTestRunner.class)
public class IntermittentTestRunnerTest {

   private static int testCounter = 0;

   @Test
   @Intermittent(repition = 99)
   public void annotatedTest() {
      testCounter++;
   }
}

(「Intermittent 의 「Intermittent Test Runner」를 사용)@RunWithtestCounter99가 됩니다.

이는 기본적으로 위의 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() { }
}

저는 이런 종류의 테스트를 할 수 있는 모듈을 만듭니다.그러나 그것은 반복적인 것 만이 아니다.하지만 어떤 코드 조각이 스레드 안전하다는 것을 보증합니다.

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

이것은 오픈 소스 프로젝트입니다.얼마든지 개선하세요.

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

            }
        }

    }

}

언급URL : https://stackoverflow.com/questions/1492856/easy-way-of-running-the-same-junit-test-over-and-over

반응형