tests runwith androidjunit4 android-testing

android testing - runwith - ¿Cuál es la diferencia entre getTargetContext() y getContext(en InstrumentationRegistry)?



@runwith androidjunit4 class (3)

Es posible que necesite InstrumentationRegistry.getContext() para acceder a los recursos sin procesar de un caso de prueba.

Por ejemplo, para acceder a la app/src/androidTest/res/raw/resource_name.json en un TestCase:

final Context context = InstrumentationRegistry.getContext(); InputStream is = context.getResources().openRawResource(com.example.package.test.R.raw.resource_name);

Estoy usando la nueva Biblioteca de compatibilidad de pruebas de Android ( com.android.support.test:runner:0.2 ) para ejecutar Pruebas de instrumentación (también conocidas como Pruebas de dispositivos o de emuladores).

@RunWith(AndroidJUnit4.class) mi clase de prueba con @RunWith(AndroidJUnit4.class) y uso Android Studio para ejecutarlos.

Para mis casos de prueba necesito una instancia de Context . Puedo obtenerlo con InstrumentationRegistry pero tiene dos métodos relacionados con el contexto y no está claro cuál es la diferencia.

¿Cuál es la diferencia entre InstrumentationRegistry.getContext() frente a InstrumentationRegistry.getTargetContext() ?


He encontrado la respuesta aquí: https://code.google.com/p/android-test-kit/wiki/AndroidJUnitRunnerUserGuide

InstrumentationRegistry es una instancia de registro expuesta que contiene una referencia a la instrumentación que se ejecuta en el proceso y sus argumentos y permite la inyección de las siguientes instancias:

  • InstrumentationRegistry.getInstrumentation() , devuelve el Instrumentation actualmente en ejecución.
  • InstrumentationRegistry.getContext() , devuelve el contexto del paquete de este Instrumentation.
  • InstrumentationRegistry.getTargetContext() , devuelve el contexto de la aplicación de destino.
  • InstrumentationRegistry.getArguments() , devuelve una copia del paquete de argumentos que se pasó a esta Instrumentación. Esto es útil cuando desea acceder a los argumentos de la línea de comando pasados ​​a Instrumentación para su prueba.

EDITAR:

Entonces, ¿cuándo usar getContext () vs getTargetContext ()?

La documentación no hace un buen trabajo explicando las diferencias, así que aquí está de mi punto de vista:

Sabes que cuando haces pruebas de instrumentación en Android, tienes dos aplicaciones:

  1. La aplicación de prueba, que ejecuta su lógica de prueba y prueba su aplicación "real"
  2. La aplicación "real" (que verán tus usuarios)

Entonces, cuando esté escribiendo sus pruebas y desee cargar un recurso de su aplicación real , use getTargetContext() .

Si desea utilizar un recurso de su aplicación de prueba (por ejemplo, una entrada de prueba para una de sus pruebas), llame a getContext() .


Me tomó horas para averiguarlo.

Un caso de InstrumentedTest tenía un miembro de contexto que se configuró en la configuración de esta manera:

context = InstrumentationRegistry.getTargetContext();

Esto fue usado para abrir archivos, especialmente cosas como esas:

String filenameOriginal = context.getCacheDir() + "/initial.csv";

Ahora decidí que necesito usar algún recurso que solo está disponible en la prueba instrumentada, no quería distribuir este recurso con la versión de lanzamiento. Por lo tanto recreé los directorios de recursos bajo prueba:

app/src/androidTest └───res └───raw v1.csv

Pero para poder usar esto en código tuve que llamar algo como esto:

public static Uri resourceToUri(Context context, int resID) { return Uri.parse(ContentResolver.SCHEME_ANDROID_RESOURCE + "://" + context.getResources().getResourcePackageName(resID) + ''/'' + context.getResources().getResourceTypeName(resID) + ''/'' + context.getResources().getResourceEntryName(resID)); } resourceToUri(context, R.raw.v1)

Lo que siempre fallaría porque R.raw.v1 coincidentemente coincidió con algo que en realidad estaba en mi archivo de recursos R de la aplicación principal. Al utilizar recursos en las pruebas instrumentadas, se generaron dos archivos R Para arreglar eso tuve que incluir el archivo de prueba R:

import com.my_thing.app.my_app.test.R;

Sin embargo, la llamada resourceToUri , sin embargo, seguirá fallando.

El problema era que no debía haber usado InstrumentationRegistry.getTargetContext() sino InstrumentationRegistry.getInstrumentation().getContext() para obtener el recurso de R.raw.v1 así que sustituyo ciegamente la configuración del contexto para toda la clase de prueba a

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

Funcionó bien para la prueba específica, pero otras pruebas en el caso de prueba comenzaron a fallar con el permiso denegado para el filenameOriginal que estaba usando anteriormente.

Resultó que al reemplazar el contexto por el contexto de instrumentación obtuve una ruta a la que mi aplicación no tenía acceso y obtuve la FileNotFoundException con permission denied y ninguna GrantTestRule u otras cosas funcionarían.

Así que tenga cuidado al usar esos contextos, podría arruinar su tiempo: /