Ottieni il contesto del progetto di test nel caso di test junit di Android


108

Qualcuno sa come puoi ottenere il contesto del progetto Test nel caso di test junit Android (estende AndroidTestCase).

Nota: il test NON è un test di strumentazione.

Nota 2: ho bisogno del contesto del progetto di test, non del contesto dell'applicazione effettiva che viene testata.

Ho bisogno di questo per caricare alcuni file dalle risorse dal progetto di test.


Perché non puoi usare semplicemente InstrumentationTestCase?
yorkw

1
Perché sto testando servizi, non l'interfaccia utente.
peceps

1
C'è una risposta migliore trovata qui: [Utilizzando AndroidTestCase invece di un test JUnit] [1] [1]: stackoverflow.com/questions/3170706/…
Jaime Botero

Risposte:


136

C'è un nuovo approccio con Android Testing Support Library (attualmente androidx.test:runner:1.1.1). Esempio aggiornato di Kotlin:

class ExampleInstrumentedTest {

    lateinit var instrumentationContext: Context

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

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

Se vuoi eseguire anche il contesto dell'app:

InstrumentationRegistry.getInstrumentation().targetContext

Esempio completo in esecuzione: https://github.com/fada21/AndroidTestContextExample

Guarda qui: qual è la differenza tra getTargetContext () e getContext (su InstrumentationRegistry)?


Finalmente una risposta su come utilizzare JUnit4 con InstrumentationTest. Dopo ore di ricerca. Devo amare lo sviluppo Android.
Fabian Zeindl

1
Bello! tx (nota che c'è un errore di battitura nel tuo membro della classe)
Greg

1
Qualcuno potrebbe aiutare su quali dipendenze devono essere aggiunte nel file gradle affinché funzioni?
Greg

1
Non dimenticare di aggiungere compile "com.android.support.test:runner:1.0.1"al tuo gradle
egorikem

2
È deprecato, usa InstrumentationRegistry.getInstrumentation().contextinvece.
Allan Veloso

37

Dopo alcune ricerche l'unica soluzione funzionante sembra essere quella già indicata da Yorkw. Dovresti estendere InstrumentationTestCase e quindi puoi accedere al contesto della tua applicazione di test usando getInstrumentation (). GetContext () - ecco un breve snippet di codice usando i suggerimenti sopra:

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
Sì, ma sembra sciocco che Android non fornisca l'accesso al contesto del progetto di test in semplici test JUnit. Il contesto è presente in AndroidTestCase.mTestContext ma è privato. Non vedo perché.
peceps

@peceps Full Ack - ma è proprio così e non mi piace nemmeno;)
AgentKnopf

25

Come puoi leggere nel codice sorgente di AndroidTestCase , il getTestContext()metodo è nascosto.

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

Puoi ignorare l' @hideannotazione usando la riflessione.

Basta aggiungere il seguente metodo nel tuo 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;
    }
}

Quindi chiama getTestContext()ogni volta che vuoi. :)


2
Ha funzionato perfettamente per me e carico le risorse utilizzando Context di AndroidTestCase tramite questo metodo o ActivityInstrumentationTestCase2.getInstrumentation () .getContext () quindi getResources () .getAssets ()
Andrew Mackenzie

Puoi speculare sul motivo per cui l'hanno nascosto? Se usiamo questa tecnica, potrebbero portare via il metodo in una versione successiva (rompendo il nostro codice di prova)?
Andrew Shepherd

1
Ottengojava.lang.NoSuchMethodException: android.test.ServiceTestCase.getTestContext()
kurdtpage

4

Aggiornamento: AndroidTestCase questa classe è stata deprecata nel livello API 24. Utilizzare InstrumentationRegistryinvece. I nuovi test dovrebbero essere scritti utilizzando la libreria di supporto per i test Android. Link all'annuncio

Dovresti estendere da AndroidTestCase invece di TestCase.

Panoramica della classe AndroidTestCase
Estendi questa opzione se devi accedere a risorse o altre cose che dipendono dal contesto dell'attività.

AndroidTestCase - Sviluppatori Android


4

Se vuoi ottenere il contesto con Kotlin e Mockito, puoi farlo nel modo seguente:

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

Spero che ti aiuti


diventando nullo nel contesto?
Deven

E non dimenticare di annotare la tua lezione di prova con @RunWith (MockitoJUnitRunner :: class)
USMAN osman

2

Questo è il modo corretto per ottenere il contesto. Altri metodi sono già deprecati

import androidx.test.platform.app.InstrumentationRegistry

InstrumentationRegistry.getInstrumentation().context

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

    private Context context = ApplicationProvider.getApplicationContext();

1

Per coloro che riscontrano questi problemi durante la creazione di test automatizzati, devi farlo:

    Context instrumentationContext;

    @Before
    public void method() {

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

        MultiDex.install(instrumentationContext);
    }

0

Le altre risposte sono obsolete. In questo momento, ogni volta che estendi AndroidTestCase, c'è un oggetto Context mContext che puoi usare.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.