source

메이븐 빌드에서 junit 테스트를 병렬로 실행하고 있습니까?

manysource 2022. 12. 13. 20:09

메이븐 빌드에서 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에서는 실행 가능한 옵션이 되도록 많은 수정이 이루어지고 있습니다.스프링에 대한 병렬 테스트를 실행할 수도 있습니다. 여기서 읽어보실 수 있습니다.

JUnit의 실험용 Parallel Computer Runner에서 영감을 얻어 독자적인 ParallelSuite Parallel Parameterized Runner를 구축했습니다.이러한 러너를 사용하면 테스트 스위트와 파라미터화된 테스트를 쉽게 병렬화할 수 있습니다.

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

Parallel Parameterized.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 Annotations 값을 이러한 병렬* 클래스 중 하나로 변경하기만 하면 됩니다.

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

tempus-tempusit은 유사한 기능을 제공합니다.자세한 내용은 문서를 참조하십시오.JUnit 4.7에 의존하며 테스트 결과를 표시하기만 하면@RunWith(ConcurrentTestRunner).

건배.

오픈 소스 라이브러리 - 로드 밸런서 테스트를 확인할 수 있습니다.다양한 테스트 클래스를 병렬로 실행하는 등 원하는 대로 작동합니다.이것은 개미 준트레벨로 통합되어 있기 때문에 테스트를 변경할 필요가 없습니다.저는 도서관의 저자 중 한 명입니다.

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

마지막으로, 지금까지 어떻게 이 문제를 해결했는가?

Junit 자체에서 제공하는 Parallel Computer를 사용하여 병렬로 테스트를 실행할 수 있습니다.여기 시작할 수 있는 작은 조각이 있습니다.

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

이는 Maven이나 다른 빌드 관리 도구에 의존하지 않기 때문에 코드에서 테스트를 실행해야 할 때 도움이 됩니다.

이렇게 하면 모든 테스트 케이스가 병렬로 실행되므로 서로 다른 테스트 케이스 간에 종속성이 있는 경우 잘못된 양성이 발생할 수 있습니다.어쨌든 당신은 상호의존적인 테스트를 하지 말아야 합니다.

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

JUnit의 경우 병렬 주니트를 살펴봅니다.

다른 선택지:Punner는 새로운 병렬 Junit Runner 및 Maven 플러그인입니다.코드를 변경할 필요가 없습니다.pom.xml에 복사합니다.

<!-- Disable default surefire based testing -->
<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-surefire-plugin</artifactId>
  <version>2.20</version>
  <configuration>
    <skip>true</skip>
  </configuration>
</plugin>

<plugin>
  <groupId>com.github.marks-yag</groupId>
  <artifactId>punner-maven-plugin</artifactId>
  <version>${version}</version>
  <configuration>
  </configuration>
  <executions>
    <execution>
      <id>test</id>
      <phase>test</phase>
      <goals>
        <goal>test</goal>
      </goals>
    </execution>
  </executions>
</plugin>

Punner는 테스트 방법을 병렬로 실행할 수 있으며 테스트 출력을 개별적으로 청결하게 유지할 수 있습니다.

Punner는 다음과 같이 mvn 콘솔 출력을 줄입니다.

[INFO] --- punner-maven-plugin:0.9.13:test (test) @ ipc ---
[INFO] Punner report directory: /Users/guile/workspace/ipc/target/punner-reports
[INFO]
[INFO] com.github.yag.ipc.IPCTest.testConnectionHandler.............. PASSED
[INFO] com.github.yag.ipc.IPCTest.testSequence....................... PASSED
[INFO] com.github.yag.ipc.IPCTest.testPartialContent................. PASSED
[INFO] com.github.yag.ipc.IPCTest.testResponseContent................ PASSED
[INFO] com.github.yag.ipc.IPCTest.testPingPong....................... PASSED
[INFO] com.github.yag.ipc.IPCTest.testServerClose.................... PASSED
[INFO] com.github.yag.ipc.IPCTest.testServerSideHeartbeatTimeout..... PASSED
[INFO] com.github.yag.ipc.IPCTest.testClientSideHeartbeatTimeout..... PASSED
[INFO] com.github.yag.ipc.IPCTest.testClientSideHeartbeat............ PASSED
[INFO] com.github.yag.ipc.IPCTest.testClientReconnect................ PASSED
[INFO]
[INFO] Tests run: 10, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 10.952 sec, Time saved: 25.919 sec.

Punner는 surefire 호환 출력을 생성합니다.또한 보고서 디렉토리에서 raw 로그 데이터와 마크다운 형식의 보고서를 가져올 수도 있습니다.

➜  ipc git:(develop) ll target/punner-reports
total 104
-rw-r--r--   1 guile  staff    11K Oct 15 23:07 TEST-com.github.yag.ipc.IPCTest.xml
-rw-r--r--   1 guile  staff   298B Oct 15 23:07 com.github.yag.ipc.IPCTest.txt
drwxr-xr-x  12 guile  staff   384B Oct  8 00:50 logs
-rw-r--r--   1 guile  staff    33K Oct 15 23:07 report.md

Punner는 제 개인 프로젝트입니다.IPC 프레임워크, 세분화된 잠금, 저널 서비스, 분산 워크플로우 엔진 등 다른 프로젝트의 유닛 테스트 단계를 가속화하기 위해 Punner를 작성했습니다.그것은 나의 대기 시간을 많이 절약해 주었다.

Punner는 아직 일부 고급 기능을 지원하지 않습니다.시험 삼아 피드백을 주시면 감사하겠습니다.

테스트는 1분 안에 TestNg 테스트로 변경할 수 있습니다(Import 변경만 하면 됩니다).TestNG는 병렬 테스트에서 가장 적합합니다.

Gridgain을 사용하여 컴퓨팅 그리드에 테스트를 분산할 수 있습니다.

언급URL : https://stackoverflow.com/questions/423627/running-junit-tests-in-parallel-in-a-maven-build