关注 Android 个关于单元测试和失败的文档

Following Android docs on unit testing and failing

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

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.

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

这对于有经验的人来说是常识,但我会写给像我这样刚起步的人。

许多唯一的教程非常混乱,由于所有内容的版本不同,我无法编译或工作。

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

所以当你在 dependencies 下看到 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"

这是我的单元测试class:

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.