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

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