使用robectric + Roboguice时,日志输出写到哪里?

时间:2022-02-26 00:00:30

I'm using Robolectric to test Android. I'm running my tests via maven, e.g.

我正在使用Robolectric来测试Android。我正在通过maven运行我的测试,例如

mvn -Dtest=LogTest test

If I have code that writes to the logs, such as

如果我有写入日志的代码,例如

Log.d("TAG", "blah");

or using Roboguice's Ln

或者使用Roboguice的Ln

Ln.d("blah");

I don't see any output in maven's surefire logs (text files).

我在maven的surefire日志(文本文件)中看不到任何输出。

Ideally, I actually want simple log statements to go to the console. I can write to the console by using System.out.println("blah"), but of course I'd rather use the supported logging APIs.

理想情况下,我实际上想要简单的日志语句转到控制台。我可以使用System.out.println(“blah”)写入控制台,但当然我宁愿使用支持的日志API。

So my question is, why am I not seeing log output at all, and how can I get the log messages written to the console?

所以我的问题是,为什么我根本看不到日志输出,如何将日志消息写入控制台?

6 个解决方案

#1


64  

I am running robolectric-2.0-alpha-3.

我正在运行robolectric-2.0-alpha-3。

What worked for me was to set in the setUp method of my test the stream to stdout

对我有用的是在我的测试的setUp方法中设置到stdout的流

Something like:

就像是:

@Before
public void setUp() throws Exception {
  ShadowLog.stream = System.out;
  //you other setup here
}

With this version of robolectric I had no success doing the same (ShadowLog.stream = System.out) in a custom TestRunner or in my TestLifeycleApplication.

使用这个版本的robolectric,我在自定义的TestRunner或TestLifeycleApplication中没有成功(ShadowLog.stream = System.out)。

Setting the system property System.setProperty("robolectric.logging","stdout"); was of no effect as well, but it might works in previous versions.

设置系统属性System.setProperty(“robolectric.logging”,“stdout”);也没有任何影响,但它可能适用于以前的版本。

#2


14  

Im using robolectric 2.3. How works for me:

我使用robolectric 2.3。对我有用:

Into my @Before:

进入我的@Before:

ShadowLog.stream = System.out;

Inside my test functions i can use (ShadowLog. have other options):

在我的测试功能中,我可以使用(ShadowLog。有其他选项):

ShadowLog.v("tag", "message");

And inside my tested class I can put some messages at log with:

在我测试的类中,我可以在日志中添加一些消息:

System.out.println("message");

#3


11  

By default, logging output when using the RobolectricTestRunner disappears. You can configure where it goes by looking at the setupLogging() method of that class.

默认情况下,使用RobolectricTestRunner时的日志输出消失。您可以通过查看该类的setupLogging()方法来配置它的位置。

To summarize, you need to set the robolectric.logging system property to either stdout, stderr, or a file path where the log should be written. I do this in the constructor of a subclass of RobolectricTestRunner that I use for all tests so that logs always get written to stdout.

总而言之,您需要将robolectric.logging系统属性设置为stdout,stderr或应写入日志的文件路径。我在RobolectricTestRunner的子类的构造函数中执行此操作,我将其用于所有测试,以便始终将日志写入stdout。

#4


5  

Add the following to your test setup before your test runs:

在测试运行之前,将以下内容添加到测试设置中:

ShadowLog.stream = System.out;
Robolectric.bindShadowClass(ShadowLog.class);

https://groups.google.com/forum/?fromgroups=#!msg/robolectric/PK-9cQQQROw/svuQzM5h_vsJ

https://groups.google.com/forum/?fromgroups=#!msg/robolectric/PK-9cQQQROw/svuQzM5h_vsJ

#5


2  

When running tests with maven all you need is something like this :

使用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>

When running the tests locally, e.g. in intellij, then all you need is an environmental variable: Just go (for intellij) to Run/Debug Configurations --> Defaults -->Junit --> VM options and add

在本地运行测试时,例如在intellij中,那么您需要的只是一个环境变量:只需(对于intellij)运行/调试配置 - >默认值 - > Junit - > VM选项并添加

-Drobolectric.logging=stdout

#6


0  

The solution that worked out best for me (or at all) was to initialize a replacement injected implementation (during testing only) of RoboGuice's Ln.Print class to do System.out printing instead of Android's Log printing, given I was actually using Robolectric to avoid having to depend on the Android subsystem to run my tests in the first place.

最适合我(或根本没有)的解决方案是初始化RoboGuice的Ln.Print类的替换注入实现(仅在测试期间)进行System.out打印而不是Android的Log打印,因为我实际上使用Robolectric来避免必须依赖Android子系统来运行我的测试。

From Ln.java:

来自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();

So basically:

所以基本上:

public class TestModule extends AbstractModule {

    @Override
    protected void configure() {
        bind(Ln.Print.class).to(TestLogPrint.class);
    }

}

and:

和:

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());
    }
}

That of course assuming the standard Robolectric init to hook the module up with RoboGuice:

那当然假设标准的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);

}

#1


64  

I am running robolectric-2.0-alpha-3.

我正在运行robolectric-2.0-alpha-3。

What worked for me was to set in the setUp method of my test the stream to stdout

对我有用的是在我的测试的setUp方法中设置到stdout的流

Something like:

就像是:

@Before
public void setUp() throws Exception {
  ShadowLog.stream = System.out;
  //you other setup here
}

With this version of robolectric I had no success doing the same (ShadowLog.stream = System.out) in a custom TestRunner or in my TestLifeycleApplication.

使用这个版本的robolectric,我在自定义的TestRunner或TestLifeycleApplication中没有成功(ShadowLog.stream = System.out)。

Setting the system property System.setProperty("robolectric.logging","stdout"); was of no effect as well, but it might works in previous versions.

设置系统属性System.setProperty(“robolectric.logging”,“stdout”);也没有任何影响,但它可能适用于以前的版本。

#2


14  

Im using robolectric 2.3. How works for me:

我使用robolectric 2.3。对我有用:

Into my @Before:

进入我的@Before:

ShadowLog.stream = System.out;

Inside my test functions i can use (ShadowLog. have other options):

在我的测试功能中,我可以使用(ShadowLog。有其他选项):

ShadowLog.v("tag", "message");

And inside my tested class I can put some messages at log with:

在我测试的类中,我可以在日志中添加一些消息:

System.out.println("message");

#3


11  

By default, logging output when using the RobolectricTestRunner disappears. You can configure where it goes by looking at the setupLogging() method of that class.

默认情况下,使用RobolectricTestRunner时的日志输出消失。您可以通过查看该类的setupLogging()方法来配置它的位置。

To summarize, you need to set the robolectric.logging system property to either stdout, stderr, or a file path where the log should be written. I do this in the constructor of a subclass of RobolectricTestRunner that I use for all tests so that logs always get written to stdout.

总而言之,您需要将robolectric.logging系统属性设置为stdout,stderr或应写入日志的文件路径。我在RobolectricTestRunner的子类的构造函数中执行此操作,我将其用于所有测试,以便始终将日志写入stdout。

#4


5  

Add the following to your test setup before your test runs:

在测试运行之前,将以下内容添加到测试设置中:

ShadowLog.stream = System.out;
Robolectric.bindShadowClass(ShadowLog.class);

https://groups.google.com/forum/?fromgroups=#!msg/robolectric/PK-9cQQQROw/svuQzM5h_vsJ

https://groups.google.com/forum/?fromgroups=#!msg/robolectric/PK-9cQQQROw/svuQzM5h_vsJ

#5


2  

When running tests with maven all you need is something like this :

使用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>

When running the tests locally, e.g. in intellij, then all you need is an environmental variable: Just go (for intellij) to Run/Debug Configurations --> Defaults -->Junit --> VM options and add

在本地运行测试时,例如在intellij中,那么您需要的只是一个环境变量:只需(对于intellij)运行/调试配置 - >默认值 - > Junit - > VM选项并添加

-Drobolectric.logging=stdout

#6


0  

The solution that worked out best for me (or at all) was to initialize a replacement injected implementation (during testing only) of RoboGuice's Ln.Print class to do System.out printing instead of Android's Log printing, given I was actually using Robolectric to avoid having to depend on the Android subsystem to run my tests in the first place.

最适合我(或根本没有)的解决方案是初始化RoboGuice的Ln.Print类的替换注入实现(仅在测试期间)进行System.out打印而不是Android的Log打印,因为我实际上使用Robolectric来避免必须依赖Android子系统来运行我的测试。

From Ln.java:

来自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();

So basically:

所以基本上:

public class TestModule extends AbstractModule {

    @Override
    protected void configure() {
        bind(Ln.Print.class).to(TestLogPrint.class);
    }

}

and:

和:

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());
    }
}

That of course assuming the standard Robolectric init to hook the module up with RoboGuice:

那当然假设标准的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);

}