2013-12-09 3 views
7

Я хочу повторно использовать некоторые интеграционные тесты для тестирования нагрузки. Я реализовал правило, которое параметрироваться аннотацией:Параллельное выполнение теста в @Rule

@Target(ElementType.METHOD) 
@Retention(RetentionPolicy.RUNTIME) 
public @interface Parallel { 

    int invocations() default 1; 

    int rampUpTime() default 0; 
} 

В моей реализации правил аннотации оцениваются и утверждение устанавливаются, который имеет метод оценки подобные:

@Override 
public void evaluate() throws Throwable { 
    ScheduledExecutorService exe = Executors.newScheduledThreadPool(invocations); 

    for (int i = 0; i < invocations; i++) { 
     ScheduledFuture<?> scheduledFuture = exe.schedule(new Runnable() { 

      @Override 
      public void run() { 
       try { 
        invocated++; 

        // Request test = Request.method(description.getTestClass(), description.getMethodName()); 
        // new JUnitCore().run(test); 

        statement.evaluate(); 
       } catch (Throwable e) { 
        e.printStackTrace(); 
       } 
      } 
     }, i * rampUpTime, this.timeUnit); 
     futures.add(scheduledFuture); 
    } 
} 

Итак, вызов evaluate завершается в Runnable() и запланирован, как описано в аннотации. Дело в том, что в моем правиле происходит только планирование, бегун не знает (или не заботится) обо всех рунах, которые работают только до тех пор, пока он не настроит весь набор тестов. Поэтому я пытаюсь добавить вызовы к evalute() тестировщику. Первая попытка заключалась в использовании JUnitCore.run(...), который, конечно, заканчивается рекурсией.

Следующая попытка состояла в том, чтобы собрать все фьючерсы и дождаться их завершения. Это отлично работает на каждой тестовой основе, но я хочу выполнить целый набор тестов параллельно. А также, в своем тестовом отчете, я вижу только, что тест выполняется один раз.

Итак, я подумал, что я использую параметризованный набор с контекстом (объект, который собирает все фьючерсы из всех тестов) в качестве параметра, но я не нашел способ продвигать этот контекстный объект к тестам, каждый тест должен иметь свои собственные параметры.

Теперь я прошу указать способ добавления нескольких исполнений из моего правила в тестовый бегун, который его выполняет.

+0

'LoadTest' от http://www.clarkware.com/software/JUnitPerf.html может помочь –

+1

Почему бы не использовать специальный инструмент для стресса? что-то вроде jMeter или Gatling? – Chiron

+0

Почему бы просто не повторно использовать существующие интеграционные тесты? Я знаю, что в JMeter можно запускать тесты JUnit, но это болезненно. Интеграционные тесты - это тесты модуля Eclipse Plugin, и можно было бы создать приложение с включенной средой тестирования eclipse и использовать его в JMeter. – CodeSeavers

ответ

2

Если я правильно понимаю вас, вы пытаетесь контролировать поведение выполнения тестового бегуна. A TestRule может быть ограниченным для достижения этой цели. Но как насчет написания собственного Runner, который управляет потоком выполнения вашего модульного теста? Просто взгляните на ParentRunner of JUnit. Оттуда вы должны получить довольно хорошую идею о том, как работает основное планирование, и, возможно, реализовать свою собственную версию org.junit.experimental.ParallelComputer.

+0

Я сделаю это. – CodeSeavers