【问题标题】:Why Log.d() print nothing when running Android Local Unit Test?为什么在运行 Android 本地单元测试时 Log.d() 什么也不打印?
【发布时间】:2016-09-08 11:37:27
【问题描述】:

我正在尝试在运行 Android 本地单元测试 时打印一些内容,但没有任何反应。怎么了?我该如何解决?

查阅了http://developer.android.com上的一些文档,发现Android Local Unit Test只是运行在我机器的JVM上,用于运行单元测试的android.jar文件不包含任何实际代码,所以Log.d()什么都不打印。如果我想打印日志,我该怎么做?

这是我的代码,FeedbackModelTest.java 位于 src/test/main 目录中。

package com.upward.reader.mvp.model;

import android.util.Log;

import com.upward.reader.mvp.bean.FeedbackBean;
import com.upward.reader.net.RequestJSONCallback;

import org.junit.Test;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

public class FeedbackModelTest {

@Test
public void postFeedback() throws Exception {
    final String url = "http://test.guguread.com/interface/app/user/feedback?";
    Map<String, String> params = new HashMap<>();
    params.put("content", "content");
    new FeedbackModel().postFeedback(url, params, new RequestJSONCallback<FeedbackBean>() {

        @Override
        public void onResponse(FeedbackBean result) throws IOException {
            Log.d("TAG", result.toString());
        }

        @Override
        public void onFailure(Exception e) {
            e.printStackTrace();
        }

    });
}

}

【问题讨论】:

  • 如果通过“本地单元测试”,你的意思是你直接在你的JVM上运行测试(例如,Android Studio中的test/,而不是androidTest/),没有LogCat,所以我不希望在任何地方看到该文本。
  • 是的,我在 jvm 上运行测试,测试代码位于 src/test/java floder。你知道在这种情况下如何打印日志吗?
  • 日志打印到 LogCat,我怀疑它会在本地单元测试中运行。不过不确定……
  • 这能回答你的问题吗? Log messages in android studio junit test

标签: android unit-testing junit


【解决方案1】:

您应该使用标准输出 System.out.println("Hello StackOverflow") 而不是 Log.x()。然后您可以在运行选项卡中看到日志信息。

2017/12/16 更新:如果您在 Run 选项卡上看不到输出,请转至 Android Monitor 选项卡查找输出。

【讨论】:

  • 这很有趣。我想知道为什么不能使用 Log / Timber 语句自动执行此操作?
  • 在 Kotlin 中,使用 'println("result: $value")' 有效。
【解决方案2】:

我建议你使用接口:

interface PlatformLog {
    fun e(tag: String, msg: String, throwable: Throwable?=null)
    fun i(tag: String, msg: String)
}

创建一个接口例如:

在单元测试中:

class SystemPlatformLog : PlatformLog {
    override fun i(tag: String, msg: String) {
        println("$tag : $msg")
    }

    override fun e(tag: String, msg: String, throwable: Throwable?) {
        println("$tag : $msg")
    }
}

在安卓中

class AndroidPlatformLog : PlatformLog {
                override fun i(tag: String, msg: String) {
                    Log.i(tag, msg)
                }

                override fun e(tag: String, msg: String, throwable: Throwable?) {
                    Log.e(tag, msg, throwable)
                }
            }

用法: 在安卓中

private val log: PlatformLog = AndroidPlatformLog()

public override fun onCreate(savedInstanceState: Bundle?) {
    log.i(TAG, "onCreate $savedInstanceState")
}

在测试中

private val log: PlatformLog = SystemPlatformLog()

@Test
fun `should log in System`() {
    log.i(TAG, "called from tests")
}

在两种情况下使用 dagger2:

@Inject lateinit var log: PlatformLog

public override fun onCreate(savedInstanceState: Bundle?) {
    log.i(TAG, "onCreate $savedInstanceState")
}

在测试中

class MyTest{

@Inject lateinit var log: PlatformLog

@Before
fun setUp() {
    val component = DaggerTestComponent.builder().testModule(TestModule()).build()
        component.inject(this)
}

@Test
fun `should log in System`() {
    log.i(TAG, "called from tests")
}
@Module
open class TestModule {

    @Provides
    @Singleton
    open fun providePlatformLog(): PlatformLog {
        return SystemPlatformLog()
    }
}
@Singleton
@Component(modules = [TestModule::class])
interface TestComponent {
    fun inject(test: MyTest)
}

【讨论】:

    【解决方案3】:

    上面的 Jell T. 答案是正确的。但如果你想使用 Timber 或 Log,你仍然可以这样做。

    您可以在 Logcat 选项卡上搜索日志:

    【讨论】:

      【解决方案4】:

      来自Unit Testing Support

      用于运行单元测试的 android.jar 文件不包含任何实际代码 - 由真实设备上的 Android 系统映像提供。相反,所有方法都会抛出异常(默认情况下)。这是为了确保您的单元测试仅测试您的代码,而不依赖于 Android 平台的任何特定行为(您没有明确模拟,例如使用 Mockito)。如果这证明有问题,您可以将下面的 sn-p 添加到您的 build.gradle 以更改此行为:

        android {
        // ...
        testOptions { 
          unitTests.returnDefaultValues = true
        }
      }
      

      【讨论】:

        【解决方案5】:

        如果您需要在测试中包含某种形式的 Android 相关代码(Log.d 就是这样),您可以使用 Robolectric 等测试框架,该框架的作用类似于您的代码引用的 Android.jar 代码.通过将测试运行器配置为在 Robolectric 中运行,并在 robolectric 的配置注释中设置正确的配置标志,您可以使用它们的日志记录方法启用日志记录。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2014-09-26
          • 1970-01-01
          • 1970-01-01
          • 2020-12-05
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多