在 android studio junit 测试中记录消息 [英] Log messages in android studio junit test

查看:23
本文介绍了在 android studio junit 测试中记录消息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 Android Studio 中运行 JUnit(方法)测试时,有没有办法打印出 Logcat(Log.i、Log.d)消息?

Is there a way to print out Logcat (Log.i, Log.d) messages when running a JUnit (method) test in Android Studio?

我可以看到 System.out.print 消息,但没有 logcat 打印输出.

I can see System.out.print message but no logcat printouts.

在运行配置(Android Studio 的 GUI 窗口)中,Android 测试下的测试有 logcat 选项,但 JUnit 测试没有.

In the runconfiguration (GUI window of Android Studio) there are logcat options for tests under Android tests but not for JUnit tests.

这有可能吗?感谢您的任何提示!

Is this possible somehow? Thanks for any hints!

推荐答案

Logcat 输出不会在单元测试中看到,因为 Logcat 是 Android 特性 - JUnit 测试只能使用标准 Java,因此 Android 特性将不起作用.

Logcat output will not be seen in unit tests because Logcat is Android feature - JUnit tests can use only standard Java, therefore Android features won't work.

您可以在单元测试中做的是将测试替身"注入到测试组件中.但是 Log.x 调用是静态的,所以你不能覆盖它们(不解析到例如 PowerMock,你应该不惜一切代价避免).

What you can do in unit tests is inject "test doubles" into tested components. But Log.x calls are static, so you can't override them (without resolving to e.g. PowerMock, which you should avoid at all costs).

因此,第一步将是引入一个非静态类,该类将充当 Log.x 调用的代理:

Therefore, the first step will be to introduce a non-static class that will behave as a proxy for Log.x calls:

/**
 * This class is a non-static logger
 */
public class Logger {

    public void e(String tag, String message) {
        Log.e(tag, message);
    }

    public void w(String tag, String message) {
        Log.w(tag, message);
    }

    public void v(String tag, String message) {
        Log.v(tag, message);
    }

    public void d(String tag, String message) {
        Log.d(tag, message);
    }
}

现在在 Log.x 调用的每个地方都使用这个类.

Use this class in every place you have Log.x calls now.

第二步是编写重定向到标准输出的 Logger 的双重测试实现:

Second step would be to write a test-double implementation of Logger that redirects to standard output:

public class UnitTestLogger extends Logger{

    @Override
    public void e(String tag, String message) {
        System.out.println("E " + tag + ": " + message);
    }

    // similar for other methods
}

最后一步是在单元测试中注入UnitTestLogger而不是Logger:

The last step is to inject UnitTestLogger instead of Logger in unit tests:

@RunWith(MockitoJUnitRunner.class)
public class SomeClassTest {

    private Logger mLogger = new UnitTestLogger();

    private SomeClass SUT;

    @Before
    public void setup() throws Exception {
        SUT = new SomeClass(/* other dependencies here */ mLogger);
    }

}

如果你想对OOP概念严格要求,你可以提取LoggerUnitTestLogger的通用接口.

If you want to be rigorously strict about OOP concepts, you can extract common interface for Logger and UnitTestLogger.

也就是说,我从未遇到过需要调查单元测试中的 Log.x 调用.我怀疑你也不需要它.您可以在调试模式下运行单元测试并在调试器中逐行执行代码,这比尝试调查 logcat 输出要快得多...

That said, I never encountered a need to investigate Log.x calls in unit tests. I suspect that you don't need it either. You can run unit tests in debug mode and step over the code line-by-line in debugger, which is much faster than attempting to investigate logcat output...

一般建议:

如果您正在测试的代码包含 Log.x 静态调用并且您的单元测试没有崩溃 - 您有问题.

If the code you are testing contains Log.x static calls and your unit tests do not crash - you have a problem.

我猜要么所有的测试都用 Robolectric 运行,或者你在 build.gradle 中有这个语句:unitTests.returnDefaultValues = true.

I'd guess that either all tests are being run with Robolectric, or you have this statement in build.gradle: unitTests.returnDefaultValues = true.

如果您使用 Robolectric 运行所有测试,那么它只是效率低下,但是如果所有 Android 调用都返回默认值,那么您的测试套件是不可靠的.我建议你在继续之前解决这个问题,因为它会在未来以某种方式咬你.

If you run all the tests with Robolectric, then it is just unefficient, but if all Android calls return default values, then you test suite is not reliable. I suggest you fix this issue before proceeding any further because it will bite you in the future one way or another.

这篇关于在 android studio junit 测试中记录消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆