Где записывается вывод журнала при использовании Robolectric + Roboguice?
Я использую Robolectric для тестирования Android. Я запускаю свои тесты через maven, например.
mvn -Dtest=LogTest test
Если у меня есть код, который записывает в журналы, например
Log.d("TAG", "blah");
или используя Roboguice Ln
Ln.d("blah");
Я не вижу выхода в журналах maven surefire (текстовые файлы).
В идеале, на самом деле я хочу, чтобы на консоль приходили простые инструкции журнала. Я могу писать на консоль, используя System.out.println("blah")
, но, конечно, я бы предпочел использовать поддерживаемые API протоколирования.
Итак, мой вопрос: почему я вообще не вижу выход журналов и как я могу получить сообщения журнала, записанные на консоль?
Ответы
Ответ 1
Я запускаю robolectric-2.0-alpha-3.
Для меня работала установка метода setUp моего теста потока на stdout
Что-то вроде:
@Before
public void setUp() throws Exception {
ShadowLog.stream = System.out;
//you other setup here
}
С этой версией robolectric я не успел сделать то же самое (ShadowLog.stream = System.out
) в пользовательском TestRunner или в моем TestLifeycleApplication.
Установка системного свойства System.setProperty("robolectric.logging","stdout");
также не имела никакого эффекта, но может работать в предыдущих версиях.
Ответ 2
Im, использующий robolectric 2.3. Как работает для меня:
В мой @Before:
ShadowLog.stream = System.out;
Внутри моих тестовых функций я могу использовать (ShadowLog. есть другие опции):
ShadowLog.v("tag", "message");
И внутри моего тестируемого класса я могу поместить некоторые сообщения в журнал с помощью:
System.out.println("message");
Ответ 3
По умолчанию вывод журнала при использовании RobolectricTestRunner исчезает. Вы можете настроить, где он находится, посмотрев метод setupLogging() этого класса.
Подводя итог, вам необходимо установить системное свойство robolectric.logging
либо stdout
, stderr
, либо путь к файлу, где должен записываться журнал. Я делаю это в конструкторе подкласса RobolectricTestRunner
, который я использую для всех тестов, чтобы журналы всегда записывались в stdout.
Ответ 4
Добавьте к тестовой настройке следующие параметры:
ShadowLog.stream = System.out;
Robolectric.bindShadowClass(ShadowLog.class);
https://groups.google.com/forum/?fromgroups=#!msg/robolectric/PK-9cQQQROw/svuQzM5h_vsJ
Ответ 5
При выполнении тестов с maven все, что вам нужно, это примерно так:
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.17</version>
<configuration>
<systemPropertyVariables>
<robolectric.logging>stdout</robolectric.logging>
</systemPropertyVariables>
</configuration>
</plugin>
При запуске тестов локально, например, в intellij, тогда все, что вам нужно, это переменная среды:
Просто зайдите (для intellij) в Run/Debug Configurations → Defaults → Junit → Параметры VM и добавьте
-Drobolectric.logging=stdout
Ответ 6
Решение, которое наилучшим образом для меня (или вообще), состояло в том, чтобы инициализировать замененную внедренную реализацию (только при тестировании) класса RoboGuice Ln.Print, чтобы делать печать System.out вместо печати журнала Android, поскольку я был фактически используя Robolectric, чтобы не зависеть от подсистемы Android для запуска моих тестов в первую очередь.
Из Ln.java:
public class Ln {
...
/**
* print is initially set to Print(), then replaced by guice during
* static injection pass. This allows overriding where the log message is delivered to.
*/
@Inject protected static Print print = new Print();
Итак, в основном:
public class TestModule extends AbstractModule {
@Override
protected void configure() {
bind(Ln.Print.class).to(TestLogPrint.class);
}
}
и
public class TestLogPrint extends Print {
public int println(int priority, String msg ) {
System.out.println(
String.format(
"%s%s",
getScope(4),
msg
)
);
return 0;
}
protected static String getScope(int skipDepth) {
final StackTraceElement trace = Thread.currentThread().getStackTrace()[skipDepth];
return String.format("%s | %s.%s | ", new Date(), trace.getFileName().replace(".java", ""), trace.getMethodName());
}
}
Конечно, предполагая, что стандартный Robolectric init подключит модуль к RoboGuice:
@Before
public void setUp() throws Exception {
Module roboGuiceModule = RoboGuice.newDefaultRoboModule(Robolectric.application);
Module productionModule = Modules.override(roboGuiceModule).with(new CustomRoboModule());
Module testModule = Modules.override(productionModule).with(new TestModule());
RoboGuice.setBaseApplicationInjector(Robolectric.application, RoboGuice.DEFAULT_STAGE, testModule);
RoboGuice.injectMembers(Robolectric.application, this);
}