2016-08-17 2 views
7

Мы использовали testng с java для выполнения интеграционных тестов для нашего кода. Мы реализовали слушателя для выполнения теста следующим образом: -Получение последовательных журналов при параллельном выполнении тестов

public class TestExecutionListener implements IInvokedMethodListener { 

    @Override 
    public void beforeInvocation(IInvokedMethod iInvokedMethod, ITestResult iTestResult) { 
     System.out.println("Testing : " + iInvokedMethod.getTestMethod().getMethodName()); 
    } 

    @Override 
    public void afterInvocation(IInvokedMethod iInvokedMethod, ITestResult iTestResult) { 
     System.out.println("Successfully Tested : " + iInvokedMethod.getTestMethod().getMethodName()); 
    } 
} 

Наш testng.xml определяется как: -

<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd" > 

<suite name="TestSuite" verbose="1" parallel="classes" thread-count="10"> 
    <listeners> 
     <listener class-name="core.TestExecutionListener"/> 
    </listeners> 

    <test name="IntegrationTests"> 
     <classes> 
      <class name="test.SomeTest1"/> 
      <class name="test.SomeTest2"/> 
      <class name="test.SomeTest3"/> 
      <class name="test.SomeTest4"/> 
      ... There are more than 20 classes 
     </classes> 
    </test> 
</suite> 

Как мы выполняем тесты, выход, который мы получаем, составляет:

Testing : SomeTest1Method1 
Testing : SomeTest2Method2 
Testing : SomeTest4Method5 
Successfully Tested : SomeTest2Method2 
Successfully Tested : SomeTest4Method5 

а то, что мы бы ожидать выход быть это: -

Testing : SomeTest1Method1 
Successfully Tested : SomeTest1Method1 
Testing : SomeTest2Method2 
Successfully Tested : SomeTest2Method2 
Testing : SomeTest4Method5 
Successfully Tested : SomeTest4Method5 

Гадание это из-за атрибута parallel="classes" в XML, поскольку изменение его false обеспечивает желаемое вывод. Но, как очевидно, изменение исполнения требует гораздо большего времени по сравнению с параллельным исполнением.

Есть ли способ запустить эти тесты параллельно, но все равно получить этот вывод в последовательности?

+0

Вход в различные регистраторы затем выходные в блоке Afterall? –

+0

@PaulHicks - дальнейшие намеки на это, пожалуйста. Не удалось получить часть регистрации в разных регистраторах. – nullpointer

+0

Используйте утилиту регистрации, например log4j. Получите от него журнал, используя что-то конкретное для вашего теста (у вас есть интерфейс IInvokedMethod, которого хватит, может быть что-то более подходящее).Войдите в него, вместо использования 'System.out'. По желанию в конце, прочитайте из всех регистраторов и соединитесь с 'System.out'. –

ответ

3

Когда вы включаете параллель, в журналах, как вы заметили, будет некоторое время между beforeInvocation и afterInvocation, и эта разница во времени варьируется от теста, чтобы проверить, следовательно, выход в шахматном порядке.

Если то, что вы хотите, начальные и конечные сообщения рядом друг с другом, то вы, в основном выбрасывая фактор времени и, таким образом можно просто добавить beforeInvocation сообщений для метода afterInvocation следующим образом:

public class TestExecutionListener implements IInvokedMethodListener { 

    @Override 
    public void beforeInvocation(IInvokedMethod iInvokedMethod, ITestResult iTestResult) { 
    } 

    @Override 
    public void afterInvocation(IInvokedMethod iInvokedMethod, ITestResult iTestResult) { 
     System.out.println("Testing : " + iInvokedMethod.getTestMethod().getMethodName()); 
     System.out.println("Successfully Tested : " + iInvokedMethod.getTestMethod().getMethodName()); 
    } 
} 

ИМО это единственный способ сделать это согласно вашей спецификации. Однако, если есть другая информация, которая должна быть собрана в ходе испытаний, то, возможно, вы могли бы буфер некоторые журналы в TestExecutionListener, например:

public class TestExecutionListener implements IInvokedMethodListener { 
    private Map<Integer, Deque<String>> logsMap = new HashMap<Integer, Deque<String>>(); 

    public void log(IInvokedMethod iInvokedMethod, String log) { 
     if(!logsMap.containsKey(iInvokedMethod.getId())) { 
      logsMap.put(iInvokedMethod.getId(), new ArrayDeque<String>()); 
     } 

     logsMap.get(iInvokedMethod.getId()).add(log); 
    } 

    @Override 
    public void beforeInvocation(IInvokedMethod iInvokedMethod, ITestResult iTestResult) { 
     log(iInvokedMethod, "Testing : " + iInvokedMethod.getTestMethod().getMethodName()); 
    } 

    @Override 
    public void afterInvocation(IInvokedMethod iInvokedMethod, ITestResult iTestResult) { 
     log(iInvokedMethod, "Successfully Tested : " + iInvokedMethod.getTestMethod().getMethodName()); 

     Deque<String> logs = logsMap.get(iInvokedMethod.getId()); 
     while(!logs.isEmpty()) { 
      System.out.println(logs.poll()); 
     } 
    } 
} 
0

В первую очередь, что я бы порекомендовал вам использовать log4j или аналогичные инструменты регистратора, который является элегантным, модульной & предоставляет множество гибких опций. Это также устанавливает путь к дизайну & ручным механизмом регистрации несколькими способами.

Если у вас есть бизнес-требование, в котором вам нужно отслеживать журналы каждого потока отдельно, вы должны рассмотреть возможность потоковой передачи этих журналов в разные файлы. Способы записи Log4j поддерживают требование записи в несколько файлов. Вы можете просто выполнить поиск в Google, вы получите много информации.

+0

Повторяя из вопроса - «Заявление о проблеме достаточно дескриптивное. Просто чтобы очистить - поиск более подходящего решения того, что уже было упомянутый в разделе комментариев о регистрации в разных регистраторах, а затем слияние журналов " – nullpointer

Смежные вопросы