동시 JUnit 테스트
두 가지 이유로 모든 테스트를 동시에 실행하고 싶은 대형 JUnit 테스트 스위트가 있습니다.
- 전체 테스트 스위트를 더 빠르게 실행하기 위해 여러 코어를 활용
- 스레드로부터 안전하지 않은 전역 개체로 인한 일부 오류를 감지하기를 바랍니다.
나는 이것이 스레드로부터 안전하도록 코드를 리팩토링하도록 강요한다는 것을 알고 있지만 좋은 것이라고 생각합니다 :-)
JUnit이 모든 테스트를 동시에 실행하도록하는 가장 좋은 방법은 무엇입니까?
JUnit에 고정되어 있습니까? TestNG 는 즉시 사용할 수있는 우수한 다중 스레드 테스트를 제공하며 JUnit 테스트와 호환됩니다 (몇 가지 변경해야 함). 예를 들어 다음과 같은 테스트를 실행할 수 있습니다.
@Test(threadPoolSize = 3, invocationCount = 9, timeOut = 10000)
public void doSomething() {
...
}
이것은 doSomething()
메소드가 3 개의 다른 스레드에 의해 9 번 호출 된다는 것을 의미 합니다.
TestNG를 강력히 추천 합니다.
나는이 질문에 대한 답을 찾고 있었고 여기에 대한 답변과 다른 곳에서 읽은 내용을 기반으로 현재 기존 테스트를 병렬로 실행하는 쉬운 기본 방법이없는 것처럼 보입니다. JUnit. 아니면 내가 찾지 못했다면. 그래서 저는이를 수행하는 간단한 JUnit Runner를 작성했습니다. 자유롭게 사용하십시오. MultiThreadedRunner 클래스의 전체 설명과 소스 코드는 http://falutin.net/2012/12/30/multithreaded-testing-with-junit/ 를 참조 하십시오 . 이 클래스를 사용하면 다음과 같이 기존 테스트 클래스에 주석을 달 수 있습니다.
@RunWith(MultiThreadedRunner.class)
다음 코드는 테스트를 병렬로 수행하거나 단일 코어 대신 여러 코어를 사용하여 실행 시간을 줄이는 방법에 대한 몇 가지 힌트를 포함 하는 독일어 책 JUnit Profiwissen 에서 가져온 요구 사항을 충족해야합니다 .
JUnit 4.6은 테스트의 병렬 실행을 제공하는 ParallelComputer 클래스를 도입했습니다. 그러나이 기능은 상위 러너에 대한 사용자 지정 스케줄러를 설정할 수있는 가능성을 제공하는 JUnit 4.7까지 공개적으로 액세스 할 수 없었습니다.
public class ParallelScheduler implements RunnerScheduler {
private ExecutorService threadPool = Executors.newFixedThreadPool(
Runtime.getRuntime().availableProcessors());
@Override
public void schedule(Runnable childStatement) {
threadPool.submit(childStatement);
}
@Override
public void finished() {
try {
threadPool.shutdown();
threadPool.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
throw new RuntimeException("Got interrupted", e);
}
}
}
public class ParallelRunner extends BlockJUnit4ClassRunner {
public ParallelRunner(Class<?> klass) throws InitializationError {
super(klass);
setScheduler(new ParallelScheduler());
}
}
이제 @RunWith(ParallelRunner.class)
각 메서드 로 테스트 클래스에 주석을 달면 자체 스레드 내에서 실행됩니다. 또한 실행중인 시스템에서 CPU 코어를 사용할 수있는만큼의 활성 스레드 만 있습니다.
여러 클래스를 병렬로 실행해야하는 경우 다음과 같이 사용자 정의 된 제품군을 정의 할 수 있습니다.
public class ParallelSuite extends Suite {
public ParallelSuite(Class<?> klass, RunnerBuilder builder)
throws InitializationError {
super(klass, builder);
setScheduler(new ParallelScheduler());
}
}
다음 변경 @RunWith(Suite.class)
으로@RunWith(ParallelSuite.class)
이전 예제에서 WildcardPatternSuite
와 Suite
같이 해당 제품군에서 직접 확장하여 fe the의 기능을 활용할 수도 있습니다 . 이를 통해 더 나아가 모든 단위 테스트 fe를 필터링 할 수 있습니다. 주석이 달린 카테고리 @Category
만 UnitTest
병렬로 실행하는 TestSuite 는 다음과 같이 보일 수 있습니다.
public interface UnitTest {
}
@RunWith(ParallelSuite.class)
@SuiteClasses("**/*Test.class")
@IncludeCategories(UnitTest.class)
public class UnitTestSuite {
}
이제 간단한 테스트 케이스는 다음과 같습니다.
@Category(UnitTest.class)
@RunWith(MockitoJUnitRunner.class)
public class SomeClassTest {
@Test
public void testSomething() {
...
}
}
는 사용 가능한 CPU 코어 수에 따라로 UnitTestSuite
끝나고 병렬 Test
로 @Category(UnitTest.class)
지정된 하위 디렉터리에있는 각 클래스를 실행 합니다.
그보다 더 간단해질 수 있는지 확실하지 않습니다. :)
분명히 Mathieu Carbou는 도움이 될 수있는 동시성을 구현했습니다!
http://java.dzone.com/articles/concurrent-junit-tests
OneJunit
@RunWith(ConcurrentJunitRunner.class)
@Concurrent(threads = 6)
public final class ATest {
@Test public void test0() throws Throwable { printAndWait(); }
@Test public void test1() throws Throwable { printAndWait(); }
@Test public void test2() throws Throwable { printAndWait(); }
@Test public void test3() throws Throwable { printAndWait(); }
@Test public void test4() throws Throwable { printAndWait(); }
@Test public void test5() throws Throwable { printAndWait(); }
@Test public void test6() throws Throwable { printAndWait(); }
@Test public void test7() throws Throwable { printAndWait(); }
@Test public void test8() throws Throwable { printAndWait(); }
@Test public void test9() throws Throwable { printAndWait(); }
void printAndWait() throws Throwable {
int w = new Random().nextInt(1000);
System.out.println(String.format("[%s] %s %s %s",Thread.currentThread().getName(), getClass().getName(), new Throwable ().getStackTrace()[1].getMethodName(), w));
Thread.sleep(w);
}
}
여러 JUnit :
@RunWith(ConcurrentSuite.class)
@Suite.SuiteClasses({ATest.class, ATest2.class, ATest3.class})
public class MySuite {
}
You can also try HavaRunner. It is a JUnit runner that runs tests in parallel by default.
HavaRunner also has handy suites: you can declare a test to be a member of a suite by adding the annotation @PartOf(YourIntegrationTestSuite.class)
onto the class. This approach differs from JUnit's, where you declare the suite memberships in the suite class.
In addition, HavaRunner suites may intialise heavy-weight objects such as an embedded web application container. HavaRunner then passes this heavy-weight object to the constructor of each suite member. This removes the need for the @BeforeClass
and @AfterClass
annotations, which are problematic, because they promote global mutable state, which in turn makes parallelisation difficult.
Lastly, HavaRunner has scenarios – a way to run the same test against different data. Scenarios reduce the need to duplicate test code.
HavaRunner has been battle-tested in two mid-size Java projects.
Ps. I'm the author of HavaRunner, and I'd appreciate your feedback on it.
참고URL : https://stackoverflow.com/questions/4970907/concurrent-junit-testing
'IT Share you' 카테고리의 다른 글
다른 가변 함수에 줄임표 전달 (0) | 2020.11.08 |
---|---|
Apache RewriteRule 지시문에서 환경 변수를 설정할 때 변수 이름 앞에 "REDIRECT_"가 붙는 이유는 무엇입니까? (0) | 2020.11.08 |
새 DbContext ()는 언제 만들어야합니까? (0) | 2020.11.08 |
java.net.SocketTimeoutException 가져 오기 : Android에서 연결 시간이 초과되었습니다. (0) | 2020.11.08 |
Ruby에서 동적 메서드 호출 (0) | 2020.11.08 |