En esta página, se describe cómo escribir un nuevo ejecutor de pruebas en Tradefed.
Segundo plano
Si te interesa saber cuál es el lugar de los ejecutores de pruebas en la arquitectura de Tradefed, consulta Estructura de un ejecutor de pruebas.
Esto no es un requisito previo para escribir un nuevo ejecutor de pruebas, ya que los ejecutores de pruebas se pueden escribir de forma independiente.
Lo mínimo: Implementa la interfaz
Lo mínimo para calificar como ejecutor de pruebas de Tradefed es implementar la interfaz IRemoteTest y, más específicamente, el método run(TestInformation testInfo, ITestInvocationListener listener)
.
Este método es el que invoca el harness cuando se usa el ejecutor de pruebas, similar a un elemento Runnable de Java.
Cada parte de ese método se considera parte de la ejecución del ejecutor de pruebas.
Informa los resultados del ejecutor de pruebas
El método run
en la interfaz base otorga acceso a un objeto de escucha de tipo ITestInvocationListener
. Este objeto es la clave para informar resultados estructurados del ejecutor de pruebas al agente.
Cuando informa resultados estructurados, un ejecutor de pruebas tiene las siguientes propiedades:
- Informa una lista adecuada de todas las pruebas que se ejecutaron, cuánto tiempo tardaron y si se aprobaron o fallaron de forma individual, o si tienen algún otro estado.
- Informa las métricas asociadas con las pruebas, si corresponde, por ejemplo, las métricas de tiempo de instalación.
- Se ajusta a la mayoría de las herramientas de infraestructura, por ejemplo, mostrar resultados y métricas, etcétera.
- Por lo general, es más fácil de depurar, ya que hay un seguimiento más detallado de la ejecución.
Dicho esto, informar resultados estructurados es opcional. Un ejecutor de pruebas puede solo querer evaluar el estado de toda la ejecución como APROBADA o FALLIDA sin detalles de la ejecución real.
Se puede llamar a los siguientes eventos en el objeto de escucha para notificar al harness el progreso actual de las ejecuciones:
- testRunStarted: Notifica el comienzo de un grupo de casos de prueba que se relacionan entre sí.
- testStarted: Notifica el inicio de un caso de prueba.
- testFailed/testIgnored: Notifica el cambio de estado del caso de prueba en curso. Un caso de prueba sin ningún cambio de estado se considera aprobado.
- testEnded: Notifica el final del caso de prueba.
- testRunFailed: Notifica que el estado general del grupo de ejecuciones de casos de prueba es una falla. Una ejecución de prueba puede ser aprobado o reprobado independientemente de los resultados de los casos de prueba según lo que se esperaba de la ejecución. Por ejemplo, un objeto binario que ejecuta varios casos de prueba podría informar que todos los casos de prueba aprobaron, pero con un código de salida de error (por cualquier motivo: archivos filtrados, etcétera).
- testRunEnded: Notifica al final del grupo de casos de prueba.
Mantener y garantizar el orden correcto de las devoluciones de llamada es responsabilidad del implementador del ejecutor de pruebas, por ejemplo, asegurarse de que se llame a testRunEnded
en caso de excepción con una cláusula finally
.
Las devoluciones de llamada de casos de prueba (testStarted
, testEnded
, etcétera) son opcionales. Una ejecución de prueba puede ocurrir sin ningún caso de prueba.
Es posible que notes que esta estructura de eventos se inspira en la estructura típica de JUnit. Esto se hace a propósito para mantener todo cerca de algo básico que los desarrolladores suelen conocer.
Genera informes de registros desde el ejecutor de pruebas
Si escribes tu propia clase o ejecutor de prueba de Tradefed, implementarás IRemoteTest y obtendrás un ITestInvocationListener
a través del método run()
. Este objeto de escucha
se puede usar para registrar archivos de la siguiente manera:
listener.testLog(String dataName, LogDataType type_of_data, InputStreamSource data);
Prueba con un dispositivo
La interfaz mínima anterior permite ejecutar pruebas muy simples que están aisladas y no requieren ningún recurso en particular, por ejemplo, pruebas de unidades de Java.
Los escritores de pruebas que deseen pasar al siguiente paso de la prueba de dispositivos necesitarán las siguientes interfaces:
- IDeviceTest permite recibir el objeto
ITestDevice
que representa el dispositivo en prueba y proporciona la API para interactuar con él. - IBuildReceiver permite que la prueba obtenga el objeto
IBuildInfo
creado en el paso del proveedor de compilación que contiene toda la información y los artefactos relacionados con la configuración de la prueba.
Por lo general, a los ejecutores de pruebas les interesan estas interfaces para obtener artefactos relacionados con la ejecución, por ejemplo, archivos adicionales, y obtener el dispositivo en prueba al que se orientará durante la ejecución.
Realiza pruebas con varios dispositivos
Tradefed admite la ejecución de pruebas en varios dispositivos al mismo tiempo. Esto es útil cuando se prueban componentes que requieren una interacción externa, como la vinculación de un teléfono y un reloj.
Para escribir un ejecutor de pruebas que pueda usar varios dispositivos, deberás implementar IMultiDeviceTest, que te permitirá recibir un mapa de ITestDevice
a IBuildInfo
que contenga la lista completa de representaciones de dispositivos y su información de compilación asociada.
Siempre se llamará al set de la interfaz antes del método run
, por lo que es seguro suponer que la estructura estará disponible cuando se llame a run
.
Pruebas al tanto de sus configuraciones
Algunas implementaciones del ejecutor de pruebas pueden necesitar información sobre la configuración general para funcionar correctamente, por ejemplo, algunos metadatos sobre la invocación o qué target_preparer
se ejecutó antes, etcétera.
Para lograrlo, un ejecutor de pruebas puede acceder al objeto IConfiguration
del que forma parte y en el que se ejecuta. Consulta la descripción del objeto de configuración para obtener más detalles.
Para la implementación del ejecutor de pruebas, deberás implementar IConfigurationReceiver para recibir el objeto IConfiguration
.
Ejecutor de pruebas flexible
Los ejecutores de pruebas pueden proporcionar una forma flexible de ejecutar sus pruebas si tienen un control detallado sobre ellas, por ejemplo, un ejecutor de pruebas de JUnit puede ejecutar cada prueba de unidades de forma individual.
Esto permite que el arnés y la infraestructura más grandes aprovechen ese control detallado y que los usuarios ejecuten parcialmente el ejecutor de pruebas a través del filtrado.
La compatibilidad con el filtrado se describe en la interfaz ITestFilterReceiver, que permite recibir conjuntos de filtros include
y exclude
para las pruebas que deben o no ejecutarse.
Nuestra convención es que se ejecutará una prueba SI Y SOLO SI coincide con uno o más de los filtros de inclusión Y no coincide con ninguno de los filtros de exclusión. Si no se proporcionan filtros de inclusión, se deben ejecutar todas las pruebas, siempre que no coincidan con ninguno de los filtros de exclusión.