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 de origen.
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 fuentes de Android.
Consulta estos ejemplos:
Agrega pruebas previas al envío a
TEST_MAPPING
paraservices.core
Agrega pruebas previas al envío a
TEST_MAPPING
paratools/dexter
con importaciones
La asignación de pruebas se basa en el programa de pruebas de Trade Federation (TF) para la ejecución de pruebas y la generación de informes de resultados.
Cómo definir grupos de prueba
Prueba los grupos de asignación de pruebas con un grupo de prueba. El nombre de un grupo de prueba puede ser cualquier cadena. Por ejemplo, presubmit puede ser el nombre de un grupo de pruebas que se ejecutan cuando se validan 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 la 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 conjuntos de pruebas:
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 conjuntogeneral-tests
, incluso si son específicas para una ABI, una cantidad de bits o funciones de hardware, como HWASan (hay un destinotest_suites
independiente para cada ABI) y aunque deban ejecutarse en un dispositivo.device-tests
es para las pruebas que dependen de capacidades específicas del dispositivo. Por lo general, estas pruebas se encuentran envendor/
. Específico del dispositivo se refiere solo a las capacidades que son exclusivas de un dispositivo, por lo que esto se aplica tanto a las pruebas de JUnit como a las de GTest (que, por lo general, deben marcarse comogeneral-tests
incluso si son específicas de la ABI).
Ejemplos:
Android.bp: test_suites: ["general-tests"],
Android.mk: LOCAL_COMPATIBILITY_SUITE := general-tests
Cómo configurar pruebas para que se ejecuten en un conjunto de pruebas
Para que una prueba se ejecute dentro de un conjunto de pruebas, debe cumplir con los siguientes requisitos:
- No debe tener ningún proveedor de compilación.
- Debe limpiar después de que termine, por ejemplo, borrar los archivos temporales que se generaron durante la prueba.
- Se deben cambiar los parámetros de configuración del sistema al valor predeterminado o al original.
No se debe suponer que un dispositivo está en un estado determinado, por ejemplo, listo para rootear. La mayoría de las pruebas no requieren privilegios de administrador para ejecutarse. Si una prueba debe requerir acceso de administrador, debe especificarlo con
RootTargetPreparer
en suAndroidTest.xml
, como en el siguiente ejemplo:<target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
Crea archivos de asignación de prueba
Para el directorio que requiere cobertura de pruebas, agrega un archivo JSON TEST_MAPPING
similar al ejemplo. Estas reglas garantizan que las pruebas se ejecuten en las verificaciones previas al envío cuando se modifique cualquier archivo en ese directorio o en cualquiera de sus subdirectorios.
Sigue un ejemplo
Aquí tienes un ejemplo de un archivo TEST_MAPPING
(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 prueba. Consulta Define grupos de prueba para obtener más información sobre los grupos de prueba.
Puedes establecer el nombre del módulo de prueba o el nombre de la prueba de integración de Trade Federation (ruta de acceso al archivo 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 reducir la cantidad de pruebas que se ejecutarán, usa opciones como include-filter
. Consulta el ejemplo de uso de include-filter
.
El parámetro de configuración host
de una prueba indica si la prueba es sin dispositivo y 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 pruebas admitidos son HostGTest
para los archivos binarios de GTest y HostTest
para las pruebas de JUnit.
El atributo file_patterns
te permite establecer una lista de cadenas de expresión regular para que coincidan con la ruta de acceso relativa de cualquier archivo de código fuente (relativa al directorio que contiene el archivo TEST_MAPPING
). En el ejemplo, la prueba CtsWindowManagerDeviceTestCases
se ejecuta en la verificación previa a la confirmación solo cuando un archivo Java comienza con Window
o Activity
, que existe en el mismo directorio que el archivo TEST_MAPPING
o cualquiera de sus subdirectorios. Las barras inversas (\) deben incluir un carácter de escape, ya que se encuentran 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 principales de la ruta de acceso importada. La asignación de pruebas permite importaciones anidadas, lo que 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 el siguiente comando:
tradefed.sh run commandAndExit [test_module] --help
Consulta Option handling in Tradefed para obtener más detalles sobre cómo funcionan las opciones.
Cómo ejecutar pruebas con Atest
Para ejecutar las reglas de pruebas previas a la confirmación de forma local, haz lo siguiente:
- Ve al directorio que contiene el archivo
TEST_MAPPING
. 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 confirmación previa (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 en los directorios superiores. Atest ubica y usa el archivo TEST_MAPPING
en el CWD y en todos sus directorios superiores.
Estructura el código fuente
En este ejemplo, se muestra cómo puedes configurar archivos TEST_MAPPING
en todo 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"
}
]}
Cómo especificar 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 y 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
(el valor predeterminado es 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 conjuntos 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 de 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 y X):
atest --test-mapping src/project_1:all
Incluir subdirectorios
De forma predeterminada, cuando se ejecutan pruebas en TEST_MAPPING
con Atest, solo se ejecutan las pruebas previas al envío configuradas en el archivo TEST_MAPPING
en el CWD (o en 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 que también incluya esas pruebas.
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 y B).
Se admiten comentarios a nivel de la línea
Puedes agregar un comentario de formato //
a nivel de la línea para completar el archivo TEST_MAPPING
con una descripción del parámetro de configuración que sigue.
ATest y Trade Federation preprocesan TEST_MAPPING
en un formato JSON válido sin comentarios. Para mantener el archivo JSON limpio, solo se admite el comentario de formato //
a nivel de la línea.
Ejemplo:
{
// For presubmit test group.
"presubmit": [
{
// Run test on module A.
"name": "A"
}
]
}