Google se compromete a promover la equidad racial para las comunidades negras. Ver cómo.
Se usó la API de Cloud Translation para traducir esta página.
Switch to English

Ejemplo de pruebas de autoinstrucción

Cuando se inicia una prueba de instrumentación, su paquete de destino se reinicia con el código de instrumentación inyectado e iniciado para su ejecución. Una excepción es que el paquete de destino aquí no puede ser el marco de la aplicación de Android en sí, es decir, el paquete de android , ya que al hacerlo se generaría una situación paradójica en la que se debería reiniciar el marco de Android, que es lo que admite las funciones del sistema, incluida la instrumentación. sí mismo.

Esto significa que una prueba de instrumentación no puede inyectarse en el marco de Android, también conocido como el servidor del sistema, para su ejecución. Para probar el marco de Android, el código de prueba puede invocar solo superficies API públicas, o aquellas expuestas a través del lenguaje de definición de interfaz de Android AIDL disponible en el árbol fuente de la plataforma. Para esta categoría de pruebas, no tiene sentido apuntar a ningún paquete en particular. Por lo tanto, es habitual que tales instrumentaciones se declaren para apuntar a su propio paquete de aplicación de prueba, como se define en su propia etiqueta <manifest> de AndroidManifest.xml .

Dependiendo de los requisitos, los paquetes de aplicaciones de prueba en esta categoría también pueden:

  • Paquete de actividades necesarias para las pruebas.
  • Comparta la identificación de usuario con el sistema.
  • Ser firmado con la clave de la plataforma.
  • Se compilará contra la fuente del marco en lugar del SDK público.

Esta categoría de pruebas de instrumentación a veces se denomina autoinstrumentación. Estos son algunos ejemplos de pruebas de autoinstrumentación en la fuente de la plataforma:

El ejemplo cubierto aquí es escribir una nueva prueba de instrumentación con el paquete de destino establecido en su propio paquete de aplicación de prueba. Esta guía utiliza la siguiente prueba como ejemplo:

Se recomienda examinar primero el código para obtener una impresión aproximada antes de continuar.

Decidir sobre una ubicación de origen

Por lo general, su equipo ya tendrá un patrón establecido de lugares para registrar el código y lugares para agregar pruebas. La mayoría del equipo posee un único repositorio git, o comparte uno con otros equipos, pero tiene un subdirectorio dedicado que contiene el código fuente del componente.

Suponiendo que la ubicación de la raíz de su fuente de componentes se encuentra en <component source root> , la mayoría de los componentes tienen carpetas src y de tests , y algunos archivos adicionales como Android.mk (o divididos en archivos .mk adicionales), el archivo de manifiesto AndroidManifest.xml y el archivo de configuración de prueba 'AndroidTest.xml'.

Dado que está agregando una nueva prueba, es probable que deba crear el directorio de tests junto a su componente src y llenarlo con contenido.

En algunos casos, su equipo podría tener más estructuras de directorios bajo tests debido a la necesidad de empaquetar diferentes conjuntos de pruebas en aplicaciones individuales. Y en este caso, deberá crear un nuevo subdirectorio bajo tests .

Independientemente de la estructura, terminará poblando el directorio de tests o el subdirectorio recién creado con archivos similares a los que hay en el directorio de instrumentation en el cambio de gerrit de muestra. Las secciones a continuación explicarán con más detalles cada archivo.

Archivo de manifiesto

Al igual que una aplicación normal, cada módulo de prueba de instrumentación necesita un archivo de manifiesto. Si nombra el archivo como AndroidManifest.xml y lo proporciona junto a Android.mk para su módulo de prueba, el archivo BUILD_PACKAGE básico BUILD_PACKAGE incluirá automáticamente.

Antes de continuar, es muy recomendable pasar primero por la Descripción general del manifiesto de la aplicación .

Esto proporciona una descripción general de los componentes básicos de un archivo de manifiesto y sus funcionalidades. Vea el ejemplo en platform_testing / tests / example / instrumentation / AndroidManifest.xml .

Aquí se incluye una instantánea para mayor comodidad:

 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="android.test.example.helloworld" >

    <uses-sdk android:minSdkVersion="21" android:targetSdkVersion="21" />

    <application>
        <uses-library android:name="android.test.runner" />
    </application>

    <instrumentation android:name="android.support.test.runner.AndroidJUnitRunner"
                     android:targetPackage="android.test.example.helloworld"
                     android:label="Hello World Test"/>

</manifest>
 

Algunas observaciones selectas en el archivo de manifiesto:

 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="android.test.example.helloworld" >
 

El atributo del package es el nombre del paquete de la aplicación: este es el identificador único que el marco de la aplicación de Android utiliza para identificar una aplicación (o en este contexto: su aplicación de prueba). Cada usuario en el sistema solo puede instalar una aplicación con ese nombre de paquete.

Además, este atributo del package es el mismo que lo que ComponentName#getPackageName() , y también lo mismo que usaría para interactuar con varios comandos sub pm través de adb shell .

Tenga en cuenta también que, aunque el nombre del paquete suele tener el mismo estilo que el nombre del paquete Java, en realidad tiene muy pocas cosas que ver con él. En otras palabras, su paquete de aplicación (o prueba) puede contener clases con cualquier nombre de paquete, aunque, por otro lado, puede optar por la simplicidad y tener su nombre de paquete Java de nivel superior en su aplicación o prueba idéntica al nombre del paquete de la aplicación.

 android:sharedUserId="android.uid.system"
 

Esto declara que en el momento de la instalación, este apk debería tener la misma identificación de usuario, es decir, identidad de tiempo de ejecución, como la plataforma central. Tenga en cuenta que esto depende de que el apk se firme con el mismo certificado que la plataforma principal (consulte LOCAL_CERTIFICATE en la sección anterior), aunque son conceptos diferentes:

  • algunos permisos o API están protegidos por firma, lo que requiere el mismo certificado de firma
  • algunos permisos o API requieren la identidad del usuario del system de la persona que llama, lo que requiere que el paquete de llamadas comparta la identificación del usuario con el system , si es un paquete separado de la plataforma central misma
 <uses-library android:name="android.test.runner" />
 

Esto es necesario para todas las pruebas de instrumentación, ya que las clases relacionadas se empaquetan en un archivo de biblioteca jar de marco separado, por lo tanto, se requieren entradas de classpath adicionales cuando el marco de aplicación invoca el paquete de prueba.

 android:targetPackage="android.test.example.helloworld"
 

Es posible que haya notado que el targetPackage aquí se declara igual que el atributo del package declarado en la etiqueta de manifest de este archivo. Como se mencionó en los conceptos básicos de las pruebas , esta categoría de prueba de instrumentación generalmente está destinada a probar las API de framework, por lo que no es muy significativo para ellos tener un paquete de aplicación específica, aparte de sí mismo.

Archivo de configuración simple

Cada nuevo módulo de prueba debe tener un archivo de configuración para dirigir el sistema de compilación con metadatos del módulo, dependencias en tiempo de compilación e instrucciones de empaquetado. En la mayoría de los casos, la opción de archivo Blueprint basada en Soong es suficiente. Para más detalles, consulte Configuración de prueba simple .

Archivo de configuración compleja

Para estos casos más complejos, también debe escribir un archivo de configuración de prueba para el arnés de prueba de Android, Trade Federation .

La configuración de prueba puede especificar opciones especiales de configuración del dispositivo y argumentos predeterminados para proporcionar la clase de prueba. Vea el ejemplo en /platform_testing/tests/example/instrumentation/AndroidTest.xml .

Aquí se incluye una instantánea para mayor comodidad:

 <configuration description="Runs sample instrumentation test.">
  <target_preparer class="com.android.tradefed.targetprep.TestFilePushSetup"/>
  <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
    <option name="test-file-name" value="HelloWorldTests.apk"/>
  </target_preparer>
  <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer"/>
  <target_preparer class="com.android.tradefed.targetprep.RunCommandTargetPreparer"/>
  <option name="test-suite-tag" value="apct"/>
  <option name="test-tag" value="SampleInstrumentationTest"/>

  <test class="com.android.tradefed.testtype.AndroidJUnitTest">
    <option name="package" value="android.test.example.helloworld"/>
    <option name="runner" value="android.support.test.runner.AndroidJUnitRunner"/>
  </test>
</configuration>
 

Algunas observaciones selectas en el archivo de configuración de prueba:

 <target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
  <option name="test-file-name" value="HelloWorldTests.apk"/>
</target_preparer>
 

Esto le dice a la Federación de Comercio que instale HelloWorldTests.apk en el dispositivo de destino usando un target_preparer especificado. Hay muchos preparadores de objetivos disponibles para los desarrolladores en Trade Federation y se pueden usar para garantizar que el dispositivo esté configurado correctamente antes de la ejecución de la prueba.

 <test class="com.android.tradefed.testtype.AndroidJUnitTest">
  <option name="package" value="android.test.example.helloworld"/>
  <option name="runner" value="android.support.test.runner.AndroidJUnitRunner"/>
</test>
 

Esto especifica la clase de prueba de la Federación de Comercio que se utilizará para ejecutar la prueba y pasa en el paquete en el dispositivo que se ejecutará y el marco del corredor de prueba que es JUnit en este caso.

Para obtener más información, consulte Configuración del módulo de prueba .

Características de JUnit4

El uso de la biblioteca de android-support-test como corredor de prueba permite la adopción de nuevas clases de prueba de estilo JUnit4, y el cambio de gerrit de muestra contiene un uso muy básico de sus características. Vea el ejemplo en /platform_testing/tests/example/instrumentation/src/android/test/example/helloworld/HelloWorldTest.java .

Si bien los patrones de prueba suelen ser específicos para los equipos de componentes, existen algunos patrones de uso generalmente útiles.

 @RunWith(JUnit4.class)
public class HelloWorldTest {
 

Una diferencia significativa en JUnit4 es que ya no se requieren pruebas para heredar de una clase de prueba base común; en su lugar, escribe pruebas en clases simples de Java y usa anotaciones para indicar ciertas configuraciones y restricciones de prueba. En este ejemplo, estamos instruyendo que esta clase se ejecute como una prueba JUnit4.

     @BeforeClass
    public static void beforeClass() {
    ...
    @AfterClass
    public static void afterClass() {
    ...
    @Before
    public void before() {
    ...
    @After
    public void after() {
    ...
    @Test
    @SmallTest
    public void testHelloWorld() {
    ...
 

Los @Before y @After anotaciones se utilizan en los métodos de junit4 para llevar a cabo configuración de prueba pre y prueba de desmontaje posterior. Del mismo modo, las anotaciones @BeforeClass y @AfterClass son utilizadas en métodos por JUnit4 para realizar la configuración antes de ejecutar todas las pruebas en una clase de prueba, y luego desmontarlas. Tenga en cuenta que la configuración del alcance de clase y los métodos de desmontaje deben ser estáticos. En cuanto a los métodos de prueba, a diferencia de la versión anterior de JUnit, ya no necesitan comenzar el nombre del método con test , en cambio, cada uno de ellos debe estar anotado con @Test . Como de costumbre, los métodos de prueba deben ser públicos, no declarar ningún valor de retorno, no tomar parámetros y pueden arrojar excepciones.

Importante : los métodos de prueba están anotados con la anotación @Test ; y tenga en cuenta que para que las pruebas se ejecuten a través de APCT, se deben anotar con tamaños de prueba: el método de ejemplo anotado testHelloWorld como @SmallTest . La anotación se puede aplicar en el alcance del método o en el alcance de la clase.

Accediendo a la instrumentation

Aunque no está cubierto en el ejemplo básico de hello world, es bastante común que una prueba de Android requiera acceso a la instancia de Instrumentation : esta es la interfaz API principal que proporciona acceso a contextos de aplicación, API de prueba relacionadas con el ciclo de vida de la actividad y más.

Debido a que las pruebas JUnit4 ya no requieren una clase base común, ya no es necesario obtener la instancia de Instrumentation través de InstrumentationTestCase#getInstrumentation() , en cambio, el nuevo corredor de pruebas lo administra a través de InstrumentationRegistry donde se almacena la configuración contextual y ambiental creada por el marco de instrumentación.

Para acceder a la instancia de la clase Instrumentation , simplemente llame al método estático getInstrumentation() en la clase InstrumentationRegistry :

 Instrumentation instrumentation = InstrumentationRegistry.getInstrumentation()
 

Construye y prueba localmente

Para los casos de uso más comunes, emplee Atest .

Para casos más complejos que requieren una personalización más pesada, siga las instrucciones de instrumentación .