2015-11-14 2 views
7

Я хотел бы запускать каждый метод, аннотированный с помощью @Test, через несколько классов, в то же время. В некоторых случаях я хотел бы ограничить это и сказать, что всего 100 человек могут запускаться в любой момент времени. Мне бы хотелось, чтобы методы с аннотациями @BeforeClass запускались один раз перед началом любого теста в классе, и мне хотелось бы, чтобы аннотации @AfterClass запускались один раз после всех тестов в классе. Я хотел бы System.out, System.err и Исключения для надлежащего буферизации/захвата, а не записи, чтобы они не чередовали, и я могу прочитать окончательный вывод и понять, что произошло.Выполнение тестов параллельно с Junit

Есть ли это? У меня есть большое количество независимых тестовых примеров, и мое приложение (я считаю) потокобезопасно. Ни один из этих тестов не имеет зависимостей от JVM, и я хочу закончить их как можно быстрее, учитывая мое оборудование.

Если этого не существует, есть ли конкретная причина, почему нет? Сколько времени у пользователей junit теряется во времени, потому что это непросто? Могу ли я построить его в Junit? На мой взгляд, это должно быть так же просто, как один флаг, и он «просто работает».

ответ

11

Вы можете выполнить это с помощью ParallelComputer от JUnit (обратите внимание, что это все еще считается экспериментальным). Это довольно простая реализация, которая поддерживается API java.util.concurrent.ExecutorService.
Если вам интересно, как это работает, check out the source.

В основном вы вызываете JUnitCore.runClasses(Computer, Classes ...) и передаете объект ParallelComputer для первого аргумента.

Пример использования:

import org.junit.Test; 
import org.junit.experimental.ParallelComputer; 
import org.junit.runner.JUnitCore; 

public class ParallelComputerExample { 

    @Test 
    public void runAllTests() { 
     Class<?>[] classes = { ParallelTest1.class, ParallelTest2.class }; 

     // ParallelComputer(true,true) will run all classes and methods 
     // in parallel. (First arg for classes, second arg for methods) 
     JUnitCore.runClasses(new ParallelComputer(true, true), classes); 
    } 

    public static class ParallelTest1 { 
     @Test 
     public void test1a() { 
      lookBusy(3000); 
     } 

     @Test 
     public void test1b() { 
      lookBusy(3000); 
     } 
    } 

    public static class ParallelTest2 { 
     @Test 
     public void test2a() { 
      lookBusy(3000); 
     } 

     @Test 
     public void test2b() { 
      lookBusy(3000); 
     } 
    } 

    public static void lookBusy(long ms) { 
     try { 
      Thread.sleep(ms); 
     } catch (InterruptedException e) { 
      System.out.println("interrupted"); 
     } 
    } 
} 

Приведенный выше код будет работать в течение 3 секунд, потому что все методы и классы побежал параллельно.

Это будет работать через 6 секунд (поскольку все классы параллельны). JUnitCore.runClasses(new ParallelComputer(true, false), classes);

Это также будет работать через 6 секунд (поскольку все методы параллельны). JUnitCore.runClasses(new ParallelComputer(false, true), classes);

+2

Вы не должны вызывать JUnitCore.runClasses() из @Test. Это испортит отчеты об испытаниях. См.: Https://github.com/junit-team/junit4/issues/1102 Реальное решение для параллельного запуска теста состоит в том, чтобы расширить Runner или Suite –

2

Да, вы можете.

Если вы используете maven. Вы можете воспользоваться помощью

Maven-верный-плагин

Весной,

Вы можете проверить это Link

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

Решение 2: Junit4 обеспечивает параллельную функцию, используя ParallelComputer

0

JUnit Toolbox предлагает JUnit бегуны для параллельного выполнения тестов.

Для того, чтобы не смешиваться вывод System.err и System.out вы должны начать тесты в отдельных виртуальных машинах, потому что System.err и System.out являются глобальными.