Uzyskaj kontekst projektu testowego w przypadku testowym junit systemu Android


108

Czy ktoś wie, jak można uzyskać kontekst projektu testowego w przypadku testu junit systemu Android (rozszerza AndroidTestCase).

Uwaga: test NIE jest testem oprzyrządowania.

Uwaga 2: Potrzebuję kontekstu projektu testowego, a nie kontekstu rzeczywistej testowanej aplikacji.

Potrzebuję tego, aby załadować niektóre pliki z zasobów z projektu testowego.


Dlaczego nie możesz po prostu użyć InstrumentationTestCase?
yorkw

1
Ponieważ testuję usługi, a nie interfejs użytkownika.
peceps

1
Tutaj znajduje się lepsza odpowiedź: [Korzystanie z AndroidTestCase zamiast testu JUnit] [1] [1]: stackoverflow.com/questions/3170706/…
Jaime Botero

Odpowiedzi:


137

Jest nowe podejście z biblioteką wsparcia testowania Androida (obecnie androidx.test:runner:1.1.1). Zaktualizowany przykład Kotlin:

class ExampleInstrumentedTest {

    lateinit var instrumentationContext: Context

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

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

Jeśli chcesz również uruchomić kontekst aplikacji:

InstrumentationRegistry.getInstrumentation().targetContext

Pełny przykład działania: https://github.com/fada21/AndroidTestContextExample

Spójrz tutaj: Jaka jest różnica między getTargetContext () i getContext (w InstrumentationRegistry)?


1
Na koniec odpowiedź, jak używać JUnit4 z InstrumentationTest. Po godzinach poszukiwań. Uwielbiam programowanie na Androida.
Fabian Zeindl,

1
Miły! tx (zauważ, że w twojej klasie jest literówka)
Greg

1
Czy ktoś mógłby pomóc, jakie zależności należy dodać w pliku gradle, aby to zadziałało?
Greg

1
Nie zapomnij dodać compile "com.android.support.test:runner:1.0.1"do swojego gradle
egorikem

2
Jest przestarzały, użyj InstrumentationRegistry.getInstrumentation().contextzamiast niego.
Allan Veloso

37

Po kilku badaniach wydaje się, że jedynym działającym rozwiązaniem jest to, na które wskazał już york. Musiałbyś rozszerzyć InstrumentationTestCase, a następnie możesz uzyskać dostęp do kontekstu swojej aplikacji testowej za pomocą metody getInstrumentation (). GetContext () - tutaj jest krótki fragment kodu wykorzystujący powyższe sugestie:

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
Tak, ale wydaje się głupie, że Android nie zapewnia dostępu do kontekstu projektu testowego w prostych testach JUnit. Kontekst znajduje się w AndroidTestCase.mTestContext, ale jest prywatny. Nie rozumiem dlaczego.
peceps

@peceps Full Ack - ale tak to już i mi się to nie podoba;)
AgentKnopf

25

Jak można przeczytać w kodzie źródłowym AndroidTestCase , getTestContext()metoda jest ukryta.

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

Możesz pominąć @hideadnotację za pomocą odbicia.

Po prostu dodaj następującą metodę w swoim 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;
    }
}

Zadzwoń w getTestContext()dowolnym momencie. :)


2
Dla mnie zadziałało idealnie i ładuję zasoby za pomocą Context albo AndroidTestCase za pomocą tej metody, albo ActivityInstrumentationTestCase2.getInstrumentation () .getContext (), a następnie getResources () .getAssets ()
Andrew Mackenzie

Czy możesz spekulować, dlaczego ukryli to? Jeśli użyjemy tej techniki, czy mogliby usunąć tę metodę w późniejszym wydaniu (łamiąc nasz kod testowy)?
Andrew Shepherd

1
Dostajęjava.lang.NoSuchMethodException: android.test.ServiceTestCase.getTestContext()
kurdtpage

4

Aktualizacja: AndroidTestCase ta klasa została wycofana na poziomie API 24. Użyj InstrumentationRegistryzamiast tego. Nowe testy należy pisać przy użyciu biblioteki obsługi testów systemu Android. Link do ogłoszenia

Należy rozszerzyć z AndroidTestCase zamiast TestCase.

Omówienie klasy AndroidTestCase
Rozszerz to, jeśli potrzebujesz dostępu do zasobów lub innych rzeczy, które zależą od kontekstu działania.

AndroidTestCase - programiści Androida


4

Jeśli chcesz uzyskać kontekst z Kotlinem i Mockito, możesz to zrobić w następujący sposób:

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

Mam nadzieję, że ci pomoże


uzyskiwanie wartości null w kontekście?
Deven

I nie zapomnij dodać adnotacji do klasy testowej za pomocą @RunWith (MockitoJUnitRunner :: class)
USMAN osman

2

To jest poprawny sposób na uzyskanie kontekstu. Inne metody są już przestarzałe

import androidx.test.platform.app.InstrumentationRegistry

InstrumentationRegistry.getInstrumentation().context

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

    private Context context = ApplicationProvider.getApplicationContext();

1

Dla tych, którzy napotykają te problemy podczas tworzenia testów automatycznych, musisz zrobić to:

    Context instrumentationContext;

    @Before
    public void method() {

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

        MultiDex.install(instrumentationContext);
    }

0

Pozostałe odpowiedzi są nieaktualne. Obecnie za każdym razem, gdy rozszerzasz AndroidTestCase, istnieje obiekt mContext Context, którego możesz użyć.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.