0

我正在尝试按照此处的示例运行简单的单元测试:

https://developer.android.com/training/testing/unit-testing/local-unit-tests

import android.content.Context;
import androidx.test.core.app.ApplicationProvider;
import org.junit.Test;

import static com.google.common.truth.Truth.assertThat;

public class UnitTestSampleJava {
    private static final String FAKE_STRING = "HELLO_WORLD";
    private Context context = ApplicationProvider.getApplicationContext();

    @Test
    public void readStringFromContext_LocalizedString() {
        // Given a Context object retrieved from Robolectric...
        ClassUnderTest myObjectUnderTest = new ClassUnderTest(context);

        // ...when the string is returned from the object under test...
        String result = myObjectUnderTest.getHelloWorldString();

        // ...then the result should be the expected one.
        assertThat(result).isEqualTo(FAKE_STRING);
    }
}

我有一个全新的项目,我按照指定设置了 gradle 文件,然后我用这一行创建了一个测试:

private Context context = ApplicationProvider.getApplicationContext();

我在该行号上得到一个例外,说明:

java.lang.IllegalStateException: No instrumentation registered! Must run under a registering instrumentation.

但是,这在文档中被列为本地单元测试,而不是仪器测试。

4

1 回答 1

1

这对于有经验的人来说是常识,但我会为那些像我一样刚起步的人写这篇文章。

许多唯一的教程非常令人困惑,由于所有内容的不同版本,我无法让它们编译或工作。

我没有意识到的第一件事是有两个不同的 Gradle 函数,testImplementation 和 androidTestImplementation。函数“testImplementation”用于普通单元测试,函数“androidTestImplementation”用于插桩单元测试(单元测试但在物理设备上运行)。

所以当你在 Gradle 中看到依赖项下的命令时:

testImplementation 'junit:junit:4.12'

这仅包括用于默认 app/src/test 文件夹中的单元测试的 JUnit 4.12,而不是 app/src/androidTest 文件夹。

如果您按照我上面链接的教程(可能已过时或根本不正确)是“androidx.test:core:1.0.0”集成了 Robolectric,并且您正在使用 Robolectric 而不调用函数或直接导入。

您不需要添加 @RunWith 注释,因为在 Gradle 文件中,教程已添加:

defaultConfig {
    testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
...
}

尽管如此,我还是无法逃脱按照教程描述的异常。所以我不得不直接包含 Robolectric:

testImplementation "org.robolectric:robolectric:4.3.1"

这是我的单元测试类:

import android.content.Context;

import androidx.test.core.app.ApplicationProvider;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;

import static org.junit.Assert.assertTrue;

@Config(maxSdk = 29)
@RunWith(RobolectricTestRunner.class)
public class UnitTestSample {
    private static final String FAKE_STRING = "HELLO_WORLD";


    @Test
    public void clickingButton_shouldChangeResultsViewText() throws Exception {
        Context context = ApplicationProvider.getApplicationContext();

        assertTrue(true);
    }
}

我必须做的另一件事是使用 @Config 将 SDK 设置为 29,因为 Robolectric 4.3.1 不支持 Android API 级别 30。

于 2020-08-17T17:34:29.037 回答