为什么运行Android Local Unit Test时Log.d()什么都不打印?

Why Log.d() print nothing when running Android Local Unit Test?

我正在尝试在运行Android Local Unit Test时打印某些内容,但没有任何反应。 怎么了? 我该如何解决?

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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
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();
        }

    });
}

}


您应该使用标准输出,Log.x()System.out.println("Hello StackOverflow") intead。然后,您可以在运行选项卡中查看日志信息。
enter image description here

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


我建议您使用界面:

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

创建一个接口,例如:

在单元测试中:

1
2
3
4
5
6
7
8
9
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")
    }
}

在Android中

1
2
3
4
5
6
7
8
9
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)
                }
            }

用法:
在Android中

1
2
3
4
5
private val log: PlatformLog = AndroidPlatformLog()

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

在测试中

1
2
3
4
5
6
private val log: PlatformLog = SystemPlatformLog()

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

或在两种情况下使用dagger2:

1
2
3
4
5
@Inject lateinit var log: PlatformLog

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

在测试中

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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)
}


如果您需要在测试中使用某种形式的与Android相关的代码(Log.d是),则可以使用诸如Robolectric之类的测试框架,该框架旨在充当代码所引用的Android.jar代码。通过将测试运行程序配置为在Robolectric中运行,并在robolectric的配置批注中设置适当的config标志,可以使用其记录方法启用记录。


来自单元测试支持:

The android.jar file that is used to run unit tests does not contain any actual code - that is provided by the Android system image on real devices. Instead, all methods throw exceptions (by default). This is to make sure your unit tests only test your code and do not depend on any particular behaviour of the Android platform (that you have not explicitly mocked e.g. using Mockito). If that proves problematic, you can add the snippet below to your build.gradle to change this behavior:

1
2
3
4
5
6
  android {
  // ...
  testOptions {
    unitTests.returnDefaultValues = true
  }
}