2009-02-19 4 views
4

Я замечаю какое-то странное поведение, используя стандартное ведение журнала во время тестов JUnit. Переводит ли JUnit стандартный вывод на другой поток? Как я могу получить доступ к этому?Weird поведение журнала JUnit

Вот простой тест JUnit, который демонстрирует поведение, которое я описываю.

@Test 
public void logMessage() { 
    // set up new logger with output directed to standard out 
    Logger logger = Logger.getLogger("my.test.logger"); 
    logger.addHandler(new StreamHandler(System.out, new SimpleFormatter())); 

    // log a warning message 
    logger.warning("logger message"); // message 1 

    // turn off parent handlers 
    logger.setUseParentHandlers(false); 

    // log a second warning message 
    logger.warning("second logger message"); // message 2 

    // print somehting to standard output 
    System.out.println("standard output message"); //message 3 
} 

Обратите внимание, что я создал новый регистратор, который просто передает свои журнальные сообщения в стандартный вывод (System.out).

Вот вывод Junit

Testsuite: com.my.FormatterTest 
Feb 19, 2009 12:02:33 PM com.my.FormatterTest logMessage 
WARNING: logger message 
standard output message 
Tests run: 1, Failures: 0, Errors: 0, Time elapsed: 0.079 sec 

------------- Standard Output --------------- 
standard output message 
------------- ---------------- --------------- 
------------- Standard Error ----------------- 
Feb 19, 2009 12:02:33 PM com.my.FormatterTest logMessage 
WARNING: logger message 
------------- ---------------- --------------- 
Feb 19, 2009 12:02:33 PM com.my.FormatterTest logMessage 
WARNING: logger message 
Feb 19, 2009 12:02:33 PM com.my.FormatterTest logMessage 
WARNING: second logger message 
test: 
BUILD SUCCESSFUL (total time: 2 seconds) 

Почему не сообщение 1 или сообщение 2 показать в Standard Output часть выходного JUnit?

Спасибо!

ответ

5

krosenvold's comments привело меня к правильному ответу (спасибо!).

Похоже, что stdout фактически перенаправляется на другой (JUnit) поток. Однако реальная проблема заключалась в том, что буфер StreamHandler не был сброшен до после. Stdout был сброшен в исходный выходной поток (в результате сообщения журнала не появлялись на выходе JUnit для stdout). Изменение кода на следующее дает правильное поведение.

@Test 
public void logMessage() { 
    // set up new logger with output directed to standard out 
    Logger logger = Logger.getLogger("my.test.logger"); 
    StreamHandler sh = new StreamHandler(System.out, new SimpleFormatter()); 
    logger.addHandler(sh); 

    // log a warning message 
    logger.warning("logger message"); // message 1 

    // turn off parent handlers 
    logger.setUseParentHandlers(false); 

    // log a second warning message 
    logger.warning("second logger message"); // message 2 

    // print somehting to standard output 
    System.out.println("standard output message"); //message 3 

    // FLUSH THE STREAM HANDLER !!! 
    sh.flush(); 
} 

yeilds

Testsuite: com.my.FormatterTest 
Feb 20, 2009 12:58:17 PM com.my.FormatterTest logMessage 
WARNING: logger message 
standard output message 
Feb 20, 2009 12:58:17 PM com.my.FormatterTest logMessage 
WARNING: logger message 
Feb 20, 2009 12:58:17 PM com.my.FormatterTest logMessage 
WARNING: second logger message 
Tests run: 1, Failures: 0, Errors: 0, Time elapsed: 0.078 sec 

------------- Standard Output --------------- 
standard output message 
Feb 20, 2009 12:58:17 PM com.my.FormatterTest logMessage 
WARNING: logger message 
Feb 20, 2009 12:58:17 PM com.my.FormatterTest logMessage 
WARNING: second logger message 
------------- ---------------- --------------- 
------------- Standard Error ----------------- 
Feb 20, 2009 12:58:17 PM com.my.FormatterTest logMessage 
WARNING: logger message 
------------- ---------------- --------------- 
test: 
BUILD SUCCESSFUL (total time: 2 seconds) 
time: 2 seconds) 
+0

+1 Спасибо! Я настраиваю тест, который выводит как файл журнала, так и консоль с обычным. Файл журнала был хорошим, но консоль продолжала печатать результаты не в порядке. Изменение его на StreamHandler устранило проблему. –

6

Как вы косвенно предполагаете, тестировщики junit перенаправляют stdout и stderr в отдельный поток во время выполнения теста. Ваш регистратор обычно инициализируется до этого перенаправления, а это означает, что он использует обычный System.out/System.err для ведения журнала на консоль.

Это можно довольно легко увидеть, посмотрев источник для класса JunitTestRunner.

Редактировать: Я рассмотрел некоторые исходные тексты, потому что ваш вопрос заставлял меня любопытно. Я не знаю, какой TestRunner вы используете, и ответ может быть там; перенаправления потоков и т. д. не являются частью структуры junit, но реализованы ant/eclipse/maven/idea. Это выглядит как вы добавляетеHandler не имеет никакого эффекта whatsovever, поэтому я подозреваю, что что-то перехватывает его (ваш вывод был бы логичным, если все журнал был выполнен родительским регистратором).

+0

В моем примере, я добавил новый обработчик к регистратору указал на System.out * внутри теста сам *. Почему это также не использует перенаправленный stdout, установленный TestRunner? – Vinnie

+0

Хорошая точка на тестировщике JUnit Test. Я использую тестовый бегун в NetBeans. Я до сих пор не понимаю, как 2 ссылки на System.out могут записывать укусы в два разных места в одном и том же методе. Для меня это головорез, и это расстраивает. – Vinnie