Cómo escribir un ejecutor de pruebas de Tradefed

En esta página, se describe cómo escribir un nuevo ejecutor de pruebas en Tradefed.

Fondo

Si tienes curiosidad sobre el lugar de los ejecutores de pruebas en la arquitectura de Tradefed, consulta Estructura de un ejecutor de pruebas.

Este no es un requisito previo para escribir un nuevo ejecutor de pruebas. Los ejecutores de pruebas se pueden escribir de forma aislada.

Requisito mínimo: Implementa la interfaz

El requisito mínimo para calificar como un 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 arnés cuando se usa el ejecutor de pruebas, de manera similar a un Java Runnable.

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 arnés.

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, fallaron o tuvieron algún otro estado de forma individual.
  • Informa las métricas asociadas con las pruebas, si corresponde, por ejemplo, las métricas de tiempo de instalación.
  • Se adapta a la mayoría de las herramientas de infraestructura, por ejemplo, muestra resultados y métricas, etcétera.
  • Por lo general, es más fácil depurar, ya que hay un seguimiento más detallado de la ejecución.

Dicho esto, informar resultados estructurados es opcional. Es posible que un ejecutor de pruebas solo quiera evaluar el estado de toda la ejecución como PASSED o FAILED sin ningún detalle de la ejecución real.

Se pueden llamar los siguientes eventos en el objeto de escucha para notificar al arnés el progreso actual de las ejecuciones:

  • testRunStarted: Notifica el comienzo de un grupo de casos de prueba relacionados entre sí.
    • testStarted: Notifica el comienzo 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 de la ejecución del grupo de casos de prueba es una falla. Una ejecución de prueba puede ser un pase o una falla independientemente de los resultados de los casos de prueba según lo que esperaba la ejecución. Por ejemplo, un objeto binario que ejecuta varios casos de prueba podría informar todos los casos de prueba aprobados , pero con un código de salida de error (por cualquier motivo: archivos filtrados, etcétera).
  • testRunEnded: Notifica el final del grupo de casos de prueba.

Mantener y garantizar el orden adecuado 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. Es posible que se produzca una ejecución de prueba sin ningún caso de prueba.

Es posible que observes que esta estructura de eventos se inspira en la estructura típica de JUnit. Esto se hace a propósito para mantener las cosas cerca de algo básico que los desarrolladores suelen conocer.

Informa registros del ejecutor de pruebas

Si escribes tu propia clase o ejecutor de pruebas 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 recursos particulares, por ejemplo, pruebas de unidades de Java.

Los escritores de pruebas que deseen pasar al siguiente paso de pruebas 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, los ejecutores de pruebas están interesados en estas interfaces para obtener artefactos relacionados con la ejecución, por ejemplo, archivos adicionales, y obtener el dispositivo en prueba que se segmentará durante la ejecución.

Prueba 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 un teléfono y un reloj que se vinculan.

Para escribir un ejecutor de pruebas que pueda usar varios dispositivos, deberás implementar IMultiDeviceTest, lo que 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 establecedor 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 que conocen sus configuraciones

Es posible que algunas implementaciones del ejecutor de pruebas necesiten 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 lograr esto, 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 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 include y exclude filtros para las pruebas que se deben o no ejecutar.

Nuestra convención es que una prueba se ejecutará 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.