Asignación de pruebas

Esta es una breve introducción a la asignación de pruebas y una explicación sobre cómo comenzar a configurar pruebas en el Proyecto de código abierto de Android (AOSP).

Acerca de la asignación de pruebas

La asignación de pruebas es un enfoque basado en Gerrit que permite a los desarrolladores crear reglas de prueba previas y posteriores al envío directamente en el árbol de origen de Android y dejar que la infraestructura de pruebas tome las decisiones sobre las ramas y los dispositivos que se probarán. Las definiciones de asignación de pruebas son archivos JSON llamados TEST_MAPPING que puedes colocar en cualquier directorio del código fuente.

Atest puede usar los archivos TEST_MAPPING para ejecutar pruebas previas al envío en los directorios asociados. Con la asignación de pruebas, puedes agregar el mismo conjunto de pruebas a las verificaciones previas al envío con un cambio mínimo dentro del árbol de origen de Android.

Consulta estos ejemplos:

La asignación de pruebas se basa en el arnés de prueba de Trade Federation (TF) para la ejecución de pruebas y la generación de informes de resultados.

Define grupos de prueba

La asignación de pruebas agrupa las pruebas con un grupo de pruebas. El nombre de un grupo de pruebas puede ser cualquier cadena. Por ejemplo, presubmit puede ser el nombre de un grupo de pruebas que se ejecutará cuando se validen los cambios. Y postsubmit pueden ser las pruebas que se usan para validar las compilaciones después de que se combinan los cambios.

Reglas de secuencia de comandos de compilación de paquetes

Para que el arnés de prueba de Trade Federation ejecute módulos de prueba para una compilación determinada, estos módulos deben tener un test_suites establecido para Soong o un LOCAL_COMPATIBILITY_SUITE establecido para Make en uno de estos dos paquetes:

  • general-tests es para pruebas que no dependen de capacidades específicas del dispositivo (como hardware específico del proveedor que la mayoría de los dispositivos no tienen). La mayoría de las pruebas deben estar en el paquete general-tests, incluso si son específicas de una ABI o bitness o funciones de hardware como HWASan (hay un objetivo test_suites independiente para cada ABI) e incluso si deben ejecutarse en un dispositivo.
  • device-tests es para pruebas que dependen de capacidades específicas del dispositivo. Por lo general, estas pruebas se encuentran en vendor/. Específico del dispositivo se refiere solo a las capacidades que son únicas para un dispositivo, por lo que esto se aplica a las pruebas de JUnit y a las pruebas de GTest (que, por lo general, deben marcarse como general-tests, incluso si son específicas de la ABI).

Ejemplos:

Android.bp: test_suites: ["general-tests"],
Android.mk: LOCAL_COMPATIBILITY_SUITE := general-tests

Configura las pruebas para que se ejecuten en un paquete de pruebas

Para que una prueba se ejecute dentro de un paquete de pruebas, debe cumplir con lo siguiente:

  • No debe tener ningún proveedor de compilación.
  • Debe limpiarse después de que finalice, por ejemplo, borrando los archivos temporales generados durante la prueba.
  • Debe cambiar la configuración del sistema al valor predeterminado o al valor original.
  • No debe suponer que un dispositivo está en un estado determinado, por ejemplo, listo para la raíz. La mayoría de las pruebas no requieren privilegios de administrador para ejecutarse. Si una prueba debe requerir la raíz, debe especificarla con RootTargetPreparer en su AndroidTest.xml, como en el siguiente ejemplo:

    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
    

Crea archivos de asignación de pruebas

Para el directorio que requiere cobertura de pruebas, agrega un archivo JSON TEST_MAPPINGsimilar al ejemplo. Estas reglas garantizan que las pruebas se ejecuten en verificaciones previas al envío cuando se tocan archivos en ese directorio o en cualquiera de sus subdirectorios.

Sigue un ejemplo

Este es un archivo TEST_MAPPING de muestra (está en formato JSON, pero admite comentarios):

{
  "presubmit": [
    // JUnit test with options and file patterns.
    {
      "name": "CtsWindowManagerDeviceTestCases",
      "options": [
        {
          "include-annotation": "android.platform.test.annotations.RequiresDevice"
        }
      ],
      "file_patterns": ["(/|^)Window[^/]*\\.java", "(/|^)Activity[^/]*\\.java"]
    },
    // Device-side GTest with options.
    {
      "name" : "hello_world_test",
      "options": [
        {
          "native-test-flag": "\"servicename1 servicename2\""
        },
        {
          "native-test-timeout": "6000"
        }
      ]
    }
    // Host-side GTest.
    {
      "name" : "net_test_avrcp",
      "host" : true
    }
  ],
  "postsubmit": [
    {
      "name": "CtsDeqpTestCases",
      "options": [
        {
          // Use regex in include-filter which is supported in AndroidJUnitTest
          "include-filter": "dEQP-EGL.functional.color_clears.*"
        }
      ]
    }
  ],
  "imports": [
    {
      "path": "frameworks/base/services/core/java/com/android/server/am"
    }
  ]
}

Establece atributos

En el ejemplo, presubmit y postsubmit son los nombres de cada grupo de pruebas. Consulta Define grupos de prueba para obtener más información sobre los grupos de pruebas.

Puedes establecer el nombre del módulo de prueba o el nombre de la prueba de integración de Trade Federation (ruta de acceso del recurso al archivo en formato XML de prueba, por ejemplo, uiautomator/uiautomator-demo) en el valor del atributo name. Ten en cuenta que el campo name no puede usar la clase name ni el método de prueba name. Para limitar las pruebas que se ejecutarán, usa opciones como include-filter. Consulta el uso de muestra de include-filter.

El parámetro de configuración host de una prueba indica si la prueba es una prueba sin dispositivo que se ejecuta en el host o no. El valor predeterminado es false, lo que significa que la prueba requiere un dispositivo para ejecutarse. Los tipos de prueba admitidos son HostGTest para los objetos binarios de GTest y HostTest para las pruebas de JUnit.

El atributo file_patterns te permite establecer una lista de cadenas de expresiones regulares para hacer coincidir la ruta de acceso relativa de cualquier archivo de código fuente (en relación con el directorio que contiene el archivo TEST_MAPPING). En el ejemplo, la prueba CtsWindowManagerDeviceTestCases se ejecuta en la etapa previa al envío solo cuando un archivo Java comienza con Window o Activity, que existe en el mismo directorio que el TEST_MAPPING archivo o cualquiera de sus subdirectorios. Las barras invertidas (\) deben escaparse, ya que están en un archivo JSON.

El atributo imports te permite incluir pruebas en otros archivos TEST_MAPPING sin copiar el contenido. También se incluyen los archivos TEST_MAPPING en los directorios superiores de la ruta de acceso importada. La asignación de pruebas permite importaciones anidadas; esto significa que dos archivos TEST_MAPPING pueden importarse entre sí, y la asignación de pruebas puede combinar las pruebas incluidas.

El atributo options contiene opciones adicionales de la línea de comandos de Tradefed.

Para obtener una lista completa de las opciones disponibles para una prueba determinada, ejecuta lo siguiente:

tradefed.sh run commandAndExit [test_module] --help

Consulta Manejo de opciones en Tradefed para obtener más detalles sobre cómo funcionan las opciones.

Ejecuta pruebas con Atest

Para ejecutar las reglas de prueba previas al envío de forma local, haz lo siguiente:

  1. Ve al directorio que contiene el archivo TEST_MAPPING.
  2. Ejecuta el siguiente comando:

    atest
    

Se ejecutan todas las pruebas previas al envío configuradas en los archivos TEST_MAPPING del directorio actual y sus directorios superiores. Atest ubica y ejecuta dos pruebas para la etapa previa al envío (A y B).

Esta es la forma más sencilla de ejecutar pruebas previas al envío en archivos TEST_MAPPING en el directorio de trabajo actual (CWD) y los directorios superiores. Atest ubica y usa el archivo TEST_MAPPING en CWD y todos sus directorios superiores.

Estructura el código fuente

En este ejemplo, se muestra cómo puedes configurar archivos TEST_MAPPING en el árbol de origen:

src
├── project_1
│   └── TEST_MAPPING
├── project_2
│   └── TEST_MAPPING
└── TEST_MAPPING

Contenido de src/TEST_MAPPING:

{
  "presubmit": [
    {
      "name": "A"
    }
  ]
}

Contenido de src/project_1/TEST_MAPPING:

{
  "presubmit": [
    {
      "name": "B"
    }
  ],
  "postsubmit": [
    {
      "name": "C"
    }
  ],
  "other_group": [
    {
      "name": "X"
    }
  ]}

Contenido de src/project_2/TEST_MAPPING:

{
  "presubmit": [
    {
      "name": "D"
    }
  ],
  "import": [
    {
      "path": "src/project_1"
    }
  ]}

Especifica los directorios de destino

Puedes especificar un directorio de destino para ejecutar pruebas en archivos TEST_MAPPING en ese directorio. El siguiente comando ejecuta dos pruebas (A, B):

atest --test-mapping src/project_1

Ejecuta reglas de prueba posteriores al envío

También puedes usar este comando para ejecutar las reglas de prueba posteriores al envío definidas en TEST_MAPPING en src_path (predeterminado en CWD) y sus directorios superiores:

atest [--test-mapping] [src_path]:postsubmit

Ejecuta solo las pruebas que no requieren un dispositivo

Puedes usar la opción --host para que Atest ejecute solo las pruebas configuradas en el host que no requiere un dispositivo. Sin esta opción, Atest ejecuta ambas pruebas, las que requieren un dispositivo y las que se ejecutan en un host que no requiere un dispositivo. Las pruebas se ejecutan en dos paquetes separados:

atest [--test-mapping] --host

Identifica grupos de prueba

Puedes especificar grupos de prueba en el comando Atest. El siguiente comando ejecuta todas las pruebas postsubmit relacionadas con los archivos del directorio src/project_1, que contiene solo una prueba (C).

También puedes usar :all para ejecutar todas las pruebas, independientemente del grupo. El siguiente comando ejecuta cuatro pruebas (A, B, C, X):

atest --test-mapping src/project_1:all

Incluye subdirectorios

De forma predeterminada, la ejecución de pruebas en TEST_MAPPING con Atest solo ejecuta pruebas previas al envío configuradas en el archivo TEST_MAPPING en CWD (o el directorio determinado) y sus directorios superiores. Si deseas ejecutar pruebas en todos los archivos TEST_MAPPING de los subdirectorios, usa la opción --include-subdir para forzar a Atest a incluir esas pruebas también.

atest --include-subdir

Sin la opción --include-subdir, Atest solo ejecuta la prueba A. Con la opción --include-subdir, Atest ejecuta dos pruebas (A, B).

Se admiten comentarios a nivel de línea

Puedes agregar un comentario de formato // a nivel de línea para completar el archivo TEST_MAPPING con una descripción del parámetro de configuración que sigue. ATest y Trade Federation procesan previamente TEST_MAPPING a un formato JSON válido sin comentarios. Para mantener limpio el archivo JSON, solo se admite el comentario de formato // a nivel de línea.

Ejemplo:

{
  // For presubmit test group.
  "presubmit": [
    {
      // Run test on module A.
      "name": "A"
    }
  ]
}