[java] Maven 빌드에서 병렬로 junit 테스트를 실행합니까?

JUnit 4.4와 Maven을 사용하고 있으며 장기 실행 통합 테스트가 많이 있습니다.

테스트 스위트 병렬화와 관련하여 단일 테스트 클래스에서 병렬로 각 테스트 메소드를 실행할 수있는 몇 가지 솔루션이 있습니다. 그러나이 모든 것들은 내가 어떤 식 으로든 테스트를 변경해야합니다.

X 스레드에서 X 개의 다른 테스트 클래스를 병렬로 실행하는 것이 훨씬 더 깨끗한 솔루션이라고 생각합니다. 수백 개의 테스트가 있으므로 개별 테스트 클래스를 스레딩하는 데는 신경 쓰지 않습니다.

이렇게 할 수있는 방법이 있습니까?



답변

Maven 플러그인 사용 :

<build>
    <plugins>
    <plugin>
        <groupId>org.apache.maven.plugins</groupId>
        <artifactId>maven-surefire-plugin</artifactId>
        <version>2.7.1</version>
        <configuration>
            <parallel>classes</parallel>
            <threadCount>5</threadCount>
        </configuration>
    </plugin>
    </plugins>
</build>


답변

junit 4.7부터 TestNG를 사용하지 않고 병렬로 테스트를 실행할 수 있습니다. 실제로 4.6 이후로 가능했지만 4.7에서는 실행 가능한 옵션이 될 수있는 많은 수정 사항이 있습니다. 여기에서 읽을 수있는 spring으로 병렬 테스트를 실행할 수도 있습니다.


답변

JUnit의 실험적인 ParallelComputer 실행기 에서 영감을 받아 나만의 ParallelSuiteParallelParameterized 실행기를 구축했습니다 . 이러한 실행기를 사용하면 테스트 스위트와 매개 변수화 된 테스트를 쉽게 병렬화 할 수 있습니다.

ParallelSuite.java

public class ParallelSuite extends Suite {

    public ParallelSuite(Class<?> klass, RunnerBuilder builder) throws InitializationError {

        super(klass, builder);

        setScheduler(new RunnerScheduler() {

            private final ExecutorService service = Executors.newFixedThreadPool(4);

            public void schedule(Runnable childStatement) {
                service.submit(childStatement);
            }

            public void finished() {
                try {
                    service.shutdown();
                    service.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
                } catch (InterruptedException e) {
                    e.printStackTrace(System.err);
                }
            }
        });
    }
}

ParallelParameterized.java

public class ParallelParameterized extends Parameterized {

    public ParallelParameterized(Class<?> arg0) throws Throwable {

        super(arg0);

        setScheduler(new RunnerScheduler() {

            private final ExecutorService service = Executors.newFixedThreadPool(8);

            public void schedule(Runnable childStatement) {
                service.submit(childStatement);
            }

            public void finished() {
                try {
                    service.shutdown();
                    service.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
                } catch (InterruptedException e) {
                    e.printStackTrace(System.err);
                }
            }
        });
    }
}

사용법은 간단합니다. @RunWith 주석 값을 이러한 Parallel * 클래스 중 하나로 변경하기 만하면 됩니다.

@RunWith(ParallelSuite.class)
@SuiteClasses({ATest.class, BTest.class, CTest.class})
public class ABCSuite {}


답변

tempus-fugit 은 비슷한 것을 제공합니다. 자세한 내용은 문서를 확인하세요. JUnit 4.7에 의존하며 테스트를 @RunWith(ConcurrentTestRunner).

건배


답변

오픈 소스 라이브러리 인 Test Load Balancer를 확인할 수 있습니다 . 요청한대로 정확하게 수행합니다. 다른 테스트 클래스를 병렬로 실행합니다. 이것은 ant-junit 수준에서 통합되므로 어쨌든 테스트를 변경할 필요가 없습니다. 저는 도서관의 저자 중 한 명입니다.

또한 프로세스 수준 샌드 박스가 필요할 수 있으므로 스레드에서 실행하지 않는 것이 좋습니다. 예를 들어, 통합 테스트에서 DB에 도달하는 경우 다른 테스트가 다른 스레드에 일부 데이터를 추가했기 때문에 한 테스트가 실패하는 것을 원하지 않습니다. 대부분의 경우 테스트는이를 염두에두고 작성되지 않습니다.

마지막으로 지금까지이 문제를 어떻게 해결 했습니까?


답변

TestNG는 그렇게 할 수 있습니다 (이것이 저의 첫 번째 반사 였고 이미 많은 테스트 케이스를 가지고있는 것을 보았습니다).

JUnit의 경우 parallel-junit를 살펴보십시오 .


답변

Junit 자체에서 제공하는 ParallelComputer를 사용하여 테스트를 병렬로 실행할 수 있습니다. 시작하는 데 도움이되는 작은 스 니펫이 있습니다.

Class[] cls = { TestCase1.class, TestCase2.class };
Result result = JUnitCore.runClasses(ParallelComputer.classes(), cls);
List<Failure> failures = result.getFailures();

Maven 또는 기타 빌드 관리 도구에 대한 종속성이 없으므로 코드에서 테스트를 실행해야 할 때 도움이됩니다.

다른 테스트 케이스간에 종속성이있는 경우 모든 테스트 케이스가 병렬로 실행되므로 오 탐지가 발생할 수 있습니다. 어쨌든 상호 의존적 인 테스트를해서는 안됩니다.