Obtener el contexto del proyecto de prueba en el caso de prueba de Android junit

108

¿Alguien sabe cómo puede obtener el contexto del proyecto de prueba en el caso de prueba de Android junit (extiende AndroidTestCase)?

Nota: La prueba NO es una prueba de instrumentación.

Nota 2: Necesito el contexto del proyecto de prueba, no el contexto de la aplicación real que se prueba.

Necesito esto para cargar algunos archivos de activos del proyecto de prueba.

peceps
fuente
¿Por qué no puede usar InstrumentationTestCase?
yorkw
1
Porque estoy probando servicios, no UI.
peceps
1
Aquí se encuentra una mejor respuesta: [Uso de AndroidTestCase en lugar de una prueba JUnit] [1] [1]: stackoverflow.com/questions/3170706/…
Jaime Botero

Respuestas:

136

Hay un nuevo enfoque con la biblioteca de compatibilidad con pruebas de Android (actualmente androidx.test:runner:1.1.1). Ejemplo actualizado de Kotlin:

class ExampleInstrumentedTest {

    lateinit var instrumentationContext: Context

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

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

Si también desea ejecutar el contexto de la aplicación:

InstrumentationRegistry.getInstrumentation().targetContext

Ejemplo de ejecución completo: https://github.com/fada21/AndroidTestContextExample

Mire aquí: ¿Cuál es la diferencia entre getTargetContext () y getContext (en InstrumentationRegistry)?

fada21
fuente
Finalmente, una respuesta sobre cómo usar JUnit4 con InstrumentationTest. Después de horas de búsqueda. Me encanta el desarrollo de Android.
Fabian Zeindl
1
¡Agradable! tx (tenga en cuenta que hay un error tipográfico en el miembro de su clase)
Greg
1
¿Podría alguien ayudarme sobre qué dependencias deben agregarse en el archivo gradle para que esto funcione?
Greg
1
No te olvides de agregar compile "com.android.support.test:runner:1.0.1"a tu gradle
egorikem
2
Está en desuso, utilícelo InstrumentationRegistry.getInstrumentation().contexten su lugar.
Allan Veloso
37

Después de algunas investigaciones, la única solución que funciona parece ser la que ya ha señalado yorkw. Tendría que extender InstrumentationTestCase y luego puede acceder al contexto de su aplicación de prueba usando getInstrumentation (). GetContext () - aquí hay un breve fragmento de código usando las sugerencias anteriores:

public class PrintoutPullParserTest extends InstrumentationTestCase {

    public void testParsing() throws Exception {
        PrintoutPullParser parser = new PrintoutPullParser();
        parser.parse(getInstrumentation().getContext().getResources().getXml(R.xml.printer_configuration));
    }
}
AgentKnopf
fuente
7
Sí, pero parece una tontería que Android no proporcione acceso al contexto del proyecto de prueba en pruebas simples de JUnit. El contexto está allí en AndroidTestCase.mTestContext pero es privado. No veo por qué.
peceps
@peceps Full Ack - pero así es como es y no me gusta tampoco;)
AgentKnopf
25

Como puede leer en el código fuente de AndroidTestCase , el getTestContext()método está oculto.

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

Puede omitir la @hideanotación mediante la reflexión.

Simplemente agregue el siguiente método en su 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;
    }
}

Entonces llama getTestContext()cuando quieras. :)

Timothée Jeannin
fuente
2
Funcionó perfectamente para mí y cargo activos usando Context, ya sea de AndroidTestCase a través de este método, o ActivityInstrumentationTestCase2.getInstrumentation () .getContext () luego getResources () .getAssets ()
Andrew Mackenzie
¿Puedes especular sobre por qué lo ocultaron? Si usamos esta técnica, ¿podrían eliminar el método en una versión posterior (rompiendo nuestro código de prueba)?
Andrew Shepherd
1
Recibojava.lang.NoSuchMethodException: android.test.ServiceTestCase.getTestContext()
kurdtpage
4

Actualización: AndroidTestCase esta clase quedó obsoleta en el nivel de API 24. Úselo en su InstrumentationRegistrylugar. Las nuevas pruebas deben escribirse utilizando la biblioteca de compatibilidad de pruebas de Android. Enlace al anuncio

Debe extender desde AndroidTestCase en lugar de TestCase.

Descripción general de la clase AndroidTestCase
Amplíe esto si necesita acceder a los recursos u otras cosas que dependen del contexto de la actividad.

AndroidTestCase - Desarrolladores de Android

eslamb
fuente
4

Si desea obtener el contexto con Kotlin y Mockito, puede hacerlo de la siguiente manera:

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

Espero que te ayude

Juanes30
fuente
obtener nulo en contexto?
Deven
Y no se olvide de anotar su clase de prueba con @RunWith (MockitoJUnitRunner :: class)
USMAN osman
2

Esta es la forma correcta de obtener el contexto. Otros métodos ya están en desuso

import androidx.test.platform.app.InstrumentationRegistry

InstrumentationRegistry.getInstrumentation().context
tomrozb
fuente
2
import androidx.test.core.app.ApplicationProvider;

    private Context context = ApplicationProvider.getApplicationContext();
eoinzy
fuente
1

Para aquellos que se encuentran con estos problemas al crear pruebas automatizadas, deben hacer esto:

    Context instrumentationContext;

    @Before
    public void method() {

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

        MultiDex.install(instrumentationContext);
    }
Sebastien FERRAND
fuente
0

Las otras respuestas están desactualizadas. Ahora mismo, cada vez que amplía AndroidTestCase, hay un objeto de contexto mContext que puede usar.

Yoni Keren
fuente