在使用Robolectric + Roboguice时,日志输出写入哪里?
我正在使用Robolectric来testingAndroid。 我正在通过maven运行我的testing,例如
mvn -Dtest=LogTest test
如果我有写入日志的代码,例如
Log.d("TAG", "blah");
或者使用Roboguice的Ln
Ln.d("blah");
我在maven的surefire日志(文本文件)中看不到任何输出。
理想情况下,我真的想要简单的日志语句去控制台。 我可以通过使用System.out.println("blah")
写入控制台,但当然我宁愿使用支持的日志API。
所以我的问题是,为什么我根本没有看到日志输出,以及如何获取日志消息写入控制台?
我正在运行robolectric-2.0-alpha-3 。
我的工作是在我的testing setUp方法设置stream到stdout
就像是:
@Before public void setUp() throws Exception { ShadowLog.stream = System.out; //you other setup here }
有了这个版本的robolectric,我在自定义TestRunner或TestLifeycleApplication中没有做同样的事情( ShadowLog.stream = System.out
)。
设置系统属性System.setProperty("robolectric.logging","stdout");
也没有效果,但它可能在以前的版本。
我使用robolectric 2.3。 如何为我工作:
进入我的@Before:
ShadowLog.stream = System.out;
在我的testing函数里面我可以使用(ShadowLog。还有其他选项):
ShadowLog.v("tag", "message");
而在我的testingclass里面,我可以在日志中写下一些信息:
System.out.println("message");
默认情况下,使用RobolectricTestRunner时的日志输出消失。 您可以通过查看该类的setupLogging()方法来configuration它的位置 。
总而言之,您需要将robolectric.logging
系统属性设置为stdout
, stderr
或写日志的文件path。 我在RobolectricTestRunner
的一个子类的构造函数中这样做,我使用它来进行所有testing,以便日志始终写入到stdout。
在testing运行之前将以下内容添加到您的testing设置中:
ShadowLog.stream = System.out; Robolectric.bindShadowClass(ShadowLog.class);
https://groups.google.com/forum/?fromgroups=#!msg/robolectric/PK-9cQQQROw/svuQzM5h_vsJ
当使用maven运行testing时,所有你需要的是这样的:
<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>
在本地运行testing时,例如在intellij中,只需要一个环境variables:只要(对于intellij)运行/debuggingconfiguration – >默认值 – > Junit – > VM选项并添加
-Drobolectric.logging=stdout
对我来说最好的解决scheme是初始化RoboGuice的Ln.Print类的replace注入实现(仅testing期间),以进行System.out打印而不是Android的日志打印,因为我实际上正在使用Robolectric来避免不得不依靠Android子系统来运行我的testing。
来自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); }