Подтвердить что ты не робот

Получение контекста в AndroidTestCase или InstrumentationTestCase в функции Android Studio Unit Test

Я получил некоторые из моих старых тестов, работающих с новой функцией поддержки unit test для Android Studio 1.1.0. При запуске gradlew testDebug тесты запускаются, но все тесты, требующие контекста, терпят неудачу, потому что getContext (AndroidTestCase)/getInstrumentation.getContext() (InstrumentationTestCase) возвращают null.

Как я могу это решить?

Здесь два варианта, которые я пробовал:

import android.content.Context;
import android.test.InstrumentationTestCase;

public class TestTest extends InstrumentationTestCase {

    Context context;

    public void setUp() throws Exception {
        super.setUp();

        context = getInstrumentation().getContext();

        assertNotNull(context);

    }

    public void testSomething() {

        assertEquals(false, true);
    }  

}

и

import android.content.Context;
import android.test.AndroidTestCase;

public class TestTest extends AndroidTestCase {

    Context context;

    public void setUp() throws Exception {
        super.setUp();

        context = getContext();

        assertNotNull(context);

    }

    public void testSomething() {

        assertEquals(false, true);
    }

}

Это мой модуль build.gradle:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 22
    buildToolsVersion "22.0.0"

    testOptions {
        unitTests.returnDefaultValues = true
    }

    defaultConfig {
        applicationId "com.example.test.penistest"
        minSdkVersion 15
        targetSdkVersion 22
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:22.0.0'
    testCompile 'junit:junit:4.12'
}

и здесь build.gradle для проекта:

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:1.1.3'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        jcenter()
    }
}

EDIT: мои тесты все работали до обновления до AS 1.1.0 и запускались на устройстве/эмуляторе.

ИЗМЕНИТЬ:

Heres 2 скриншотов неудачных инструментов InstrumentationTestCase и AndroidTestCase:

enter image description here

enter image description here

4b9b3361

Ответ 1

Обновлено - Пожалуйста, используйте Espresso для написания контрольных тестов

Новые примеры:

У меня эти работают без развертывания на устройстве. Поместите тесты в папку /src/main/test/.

Вот более новые примеры, я взял ваши примеры и протестировал их в своем собственном временном тестовом проекте. Я провел тесты через командную строку: ./gradlew clean test. Подробнее читайте здесь: https://sites.google.com/a/android.com/tools/tech-docs/unit-testing-support.

Верх build.gradle:

// Top-level build file where you can add configuration options common to all sub-projects/modules.

buildscript {
    repositories {
        jcenter()
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:1.1.3'

        // NOTE: Do not place your application dependencies here; they belong
        // in the individual module build.gradle files
    }
}

allprojects {
    repositories {
        jcenter()
    }
}

Приложение build.gradle:

apply plugin: 'com.android.application'

android {
    compileSdkVersion 22
    buildToolsVersion "22.0.0"

    defaultConfig {
        applicationId "com.test"
        minSdkVersion 9
        targetSdkVersion 22
        versionCode 1
        versionName "1.0"
    }
    buildTypes {
        release {
            minifyEnabled false
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }

    testOptions { // <-- You need this
        unitTests {
            returnDefaultValues = true
        }
    }
}

dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:22.0.0'

    testCompile 'junit:junit:4.12' // <-- You need this
}

Основные тесты:

InstrumentationTestCaseTest для проверки Context и Assertions.

import android.content.Context;
import android.test.InstrumentationTestCase;
import android.test.mock.MockContext;

public class InstrumentationTestCaseTest extends InstrumentationTestCase {

    Context context;

    public void setUp() throws Exception {
        super.setUp();

        context = new MockContext();

        assertNotNull(context);

    }

    public void testSomething() {

        assertEquals(false, true);
    }

}

ActivityTestCase, чтобы проверить ваш Resources.

import android.content.Context;
import android.content.res.Resources;
import android.test.ActivityTestCase;

public class ActivityTestCaseTest extends ActivityTestCase {

    public void testFoo() {

        Context testContext = getInstrumentation().getContext();
        Resources testRes = testContext.getResources();

        assertNotNull(testRes);
        assertNotNull(testRes.getString(R.string.app_name));
    }
}

AndroidTestCase для проверки Context и Assertions.

import android.content.Context;
import android.test.AndroidTestCase;
import android.test.mock.MockContext;

public class AndroidTestCaseTest extends AndroidTestCase {

    Context context;

    public void setUp() throws Exception {
        super.setUp();

        context = new MockContext();

        setContext(context);

        assertNotNull(context);

    }

    // Fake failed test
    public void testSomething()  {
        assertEquals(false, true);
    }
}

Примеры поиска в Googling:

После того, как Google Gogling сильно погубит эту ошибку, я полагаю, что ваша ставка заключается в использовании getInstrumentation().getContext().getResources().openRawResource(R.raw.your_res). или чего-то подобного для проверки ваших ресурсов.

Использование InstrumentationTestCase:

Ресурсы тестирования:

public class PrintoutPullParserTest extends InstrumentationTestCase {

    public void testParsing() throws Exception {
        PrintoutPullParser parser = new PrintoutPullParser();
        parser.parse(getInstrumentation().getContext().getResources().getXml(R.xml.printer_configuration));
    }
}

Источник: fooobar.com/questions/92721/... и fooobar.com/questions/150710/...

Использование ActivityTestCase:

Ресурсы тестирования:

public class Test extends ActivityTestCase {

   public void testFoo() {  

      // .. test project environment
      Context testContext = getInstrumentation().getContext();
      Resources testRes = testContext.getResources();
      InputStream ts = testRes.openRawResource(R.raw.your_res);

      assertNotNull(testRes);
   }    
}

Источник: fooobar.com/questions/150711/...

Использование AndroidTestCase:

Получение Context (простой взлом):

private Context getTestContext() {
    try {
        Method getTestContext = ServiceTestCase.class.getMethod("getTestContext");
        return (Context) getTestContext.invoke(this);
    } catch (final Exception exception) {
        exception.printStackTrace();
        return null;
    }
}

Источник: fooobar.com/questions/92721/...

Но если вы посмотрите исходный код AndroidTestCase, похоже, вам нужно установить Context самостоятельно:

Источник: http://alvinalexander.com/java/jwarehouse/android/core/java/android/test/AndroidTestCase.java.shtml

Ответ 2

Используя Android Supporting Library, вы можете

  • get test apk context с InstrumentationRegistry.getContext()
  • получить контекст app apk с помощью InstrumentationRegistry.getTargetContext()
  • получить Инструментарий с InstrumentationRegistry.getInstrumentation()

См. нижнюю часть связанной страницы о том, как добавить в свой проект библиотеку поддержки тестирования.

Ответ 3

Вот недавний способ настройки (модульных) контрольно-измерительных приборов

Настроить

В вашем build.gradle добавьте:

testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner"

и следующие зависимости:

// Instrumentation tests
androidTestImplementation "com.android.support.test:runner:$supportTestRunnerVersion"
// To use assertThat syntax
androidTestImplementation "org.assertj:assertj-core:$assertJVersion"

Пример класса

public class Example {

    public Object doSomething() {
        // Context is used here
    }

}

Пример теста

import android.content.Context;
import android.support.test.InstrumentationRegistry;
import android.support.test.runner.AndroidJUnit4;

import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;

import static org.assertj.core.api.Assertions.assertThat;

@RunWith(AndroidJUnit4.class)
public class ExampleTest {

    private Context context;

    @Before
    public void setUp() {
        // In case you need the context in your test
        context = InstrumentationRegistry.getTargetContext();
    }

    @Test
    public void doSomething() {
        Example example = new Example();
        assertThat(example.doSomething()).isNotNull();
    }

}

Документация

Ответ 4

Я получал ошибку при попытке выполнить вызовы SQLite с помощью ответа @taynguyen, поэтому вместо:

InstrumentationRegistry.getContext()

Я использовал:

InstrumentationRegistry.getTargetContext()

Чтобы получить контекст целевого приложения вместо контекста Instrumentation.

Ответ 5

Context нужно ссылаться на то, что расширяет Context, например класс Activity или Application.

Context context = new Activity(); 

Другой вариант - использовать Robolectric.Application.