Отримайте контекст тестового проекту в тестовому випадку Android


108

Хтось знає, як можна отримати контекст проекту тестування в тестовому випадку Android (розширює AndroidTestCase).

Примітка. Тест НЕ є інструментальним випробуванням.

Примітка 2: Мені потрібен контекст тестового проекту, а не контекст фактичної тестованої програми.

Мені потрібно це для завантаження деяких файлів із активів тестового проекту.


Чому ви не можете просто використовувати InstrumentationTestCase?
yorkw

1
Тому що я тестую послуги, а не інтерфейс користувача.
пецепс

1
Тут знайдено кращу відповідь: [Використання AndroidTestCase замість тесту JUnit] [1] [1]: stackoverflow.com/questions/3170706/…
Хайме Ботеро

Відповіді:


137

З Бібліотекою підтримки Android-тестування (на даний момент androidx.test:runner:1.1.1) з'явився новий підхід . Котлін оновив приклад:

class ExampleInstrumentedTest {

    lateinit var instrumentationContext: Context

    @Before
    fun setup() {
        instrumentationContext = InstrumentationRegistry.getInstrumentation().context
    }

    @Test
    fun someTest() {
        TODO()
    }
}

Якщо також потрібно запустити контекст програми:

InstrumentationRegistry.getInstrumentation().targetContext

Повний приклад роботи: https://github.com/fada21/AndroidTestContextExample

Подивіться тут: Яка різниця між getTargetContext () та getContext (у InstrumentationRegistry)?


Нарешті відповідь про те, як використовувати JUnit4 з InstrumentationTest. Після годин пошуків. Треба любити розробку Android.
Фабіан Зейндл

1
Приємно! tx (зауважте, що у вашого класу є друкарська помилка)
Грег,

1
Може хтось допоможе про те, які залежності потрібно додати у файл gradle, щоб це працювало?
Грег

1
Не забудьте додати compile "com.android.support.test:runner:1.0.1"до своєї студії
egorikem

2
Застаріле, InstrumentationRegistry.getInstrumentation().contextзамість цього використовуйте .
Allan Veloso

37

Після деяких досліджень, здається, єдиним робочим рішенням є те, яке вже вказувало йоркве. Вам доведеться розширити InstrumentationTestCase, а потім ви можете отримати доступ до контексту своєї тестової програми за допомогою getInstrumentation (). GetContext () - ось короткий фрагмент коду, використовуючи наведені вище пропозиції:

public class PrintoutPullParserTest extends InstrumentationTestCase {

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

7
Так, але здається нерозумним, що Android не надає доступ до контексту тестового проекту у простих тестах JUnit. Контекст є в AndroidTestCase.mTestContext, але він приватний. Я не бачу чому.
peceps

@peceps Full Ack - але ось як воно є, і мені це теж не подобається;)
AgentKnopf

25

Як ви можете прочитати у вихідному коді AndroidTestCase , getTestContext()метод прихований.

/**
 * @hide
 */
public Context getTestContext() {
    return mTestContext;
}

@hideАнотацію можна обійти за допомогою рефлексії.

Просто додайте наступний метод у свій AndroidTestCase:

/**
 * @return The {@link Context} of the test project.
 */
private Context getTestContext()
{
    try
    {
        Method getTestContext = ServiceTestCase.class.getMethod("getTestContext");
        return (Context) getTestContext.invoke(this);
    }
    catch (final Exception exception)
    {
        exception.printStackTrace();
        return null;
    }
}

Тоді зателефонуйте в getTestContext()будь-який час. :)


2
Я працював ідеально для мене, і я завантажую активи за допомогою Context або AndroidTestCase за допомогою цього методу, або ActivityInstrumentationTestCase2.getInstrumentation () .getContext (), а потім getResources () .getAssets ()
Ендрю Макензі

Чи можете ви міркувати, чому вони це приховали? Якщо ми використовуємо цю методику, чи могли вони відняти метод у подальшому випуску (порушивши наш тестовий код)?
Андрій Пастух

1
Я отримуюjava.lang.NoSuchMethodException: android.test.ServiceTestCase.getTestContext()
kurdtpage

4

Оновлення: AndroidTestCase цей клас був застарілий на рівні API 24. Використовуйте InstrumentationRegistryзамість цього. Нові тести слід писати за допомогою бібліотеки підтримки Android-тестування. Посилання на оголошення

Вам слід поширитись на AndroidTestCase замість TestCase.

Огляд класу AndroidTestCase Розгорніть
це, якщо вам потрібно отримати доступ до ресурсів або інших речей, які залежать від контексту діяльності.

AndroidTestCase - Android Developers


4

Якщо ви хочете отримати контекст з Котліном та Мокіто, ви можете зробити це наступним чином:

val context = mock(Context::class.java)

Я сподіваюся, що її допоможе вам


стає нульовим у контексті?
Deven

І не забудьте анотувати ваш тестовий клас з @RunWith (MockitoJUnitRunner :: class)
USMAN osman

2

Це правильний спосіб отримати контекст. Інші методи вже застаріли

import androidx.test.platform.app.InstrumentationRegistry

InstrumentationRegistry.getInstrumentation().context

2
import androidx.test.core.app.ApplicationProvider;

    private Context context = ApplicationProvider.getApplicationContext();

1

Для тих, хто стикається з цими проблемами під час створення автоматизованих тестів, ви повинні зробити це:

    Context instrumentationContext;

    @Before
    public void method() {

        instrumentationContext = InstrumentationRegistry.getInstrumentation().getContext();

        MultiDex.install(instrumentationContext);
    }

0

Інші відповіді застаріли. Зараз кожен раз, коли ви розширюєте AndroidTestCase, з'являється об'єкт mContext Context, який ви можете використовувати.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.