En este instructivo, aprenderás a crear “Hello World” Federación de Comercio (Tradefed o TF) y ofrece una introducción práctica a la TF en un framework de aplicaciones. A partir de un entorno de desarrollo, configuración y agregar funciones.
El tutorial presenta el proceso de desarrollo de prueba como un conjunto de ejercicios, cada uno de varios pasos que demuestran cómo compilar definir mejor tu configuración. Todo el código de muestra que necesitas para completar la prueba se proporciona la configuración y el título de cada ejercicio se anota con una carta que describa las funciones involucradas en ese paso:
- D para el desarrollador
- I para Integrator
- R para el ejecutor de pruebas
Después de completar el instructivo, tendrás una configuración de TF en funcionamiento y comprenda muchos conceptos importantes del framework de TF.
Configurar la Federación de Comercio
Para obtener detalles sobre la configuración del entorno de desarrollo de TF, consulta Máquina Configuración. En el resto de este instructivo, se da por sentado que tienes una shell abierta inicializado en el entorno de TF.
Para simplificar, en este instructivo se ilustra cómo agregar una configuración y sus a la biblioteca principal del framework de TF. Esto se puede extender al desarrollo fuera del árbol de fuentes con la compilación del JAR de intercambio y, luego, los módulos con ese JAR.
Crear una clase de prueba (D)
Creemos una prueba de Hello World que solo vuelque un mensaje en stdout. R la prueba de Tradefed generalmente implementa IRemoteTest; interfaz de usuario. Esta es una implementación para HelloWorldTest:
package com.android.tradefed.example; import com.android.tradefed.device.DeviceNotAvailableException; import com.android.tradefed.invoker.TestInformation; import com.android.tradefed.log.LogUtil.CLog; import com.android.tradefed.result.ITestInvocationListener; import com.android.tradefed.testtype.IRemoteTest; public class HelloWorldTest implements IRemoteTest { @Override public void run(TestInformation testInfo, ITestInvocationListener listener) throws DeviceNotAvailableException { CLog.i("Hello, TF World!"); } }
Guarda este código de muestra en
<tree>/tools/tradefederation/core/src/com/android/tradefed/example/HelloWorldTest.java
y recompilar el intercambio desde la shell:
m -jN
Ten en cuenta que CLog.i
en el ejemplo anterior se usa para dirigir la salida a la consola. Más
En Registro (D, I, R), se describe la información sobre la creación de registros en la Federación de Comercio.
Si la compilación no se realiza correctamente, consulta Máquina Configuración para asegurarte de no perderte ningún paso.
Crear una configuración (I)
Las pruebas de la Federación de Comercio se pueden ejecutar creando un Configuration, un archivo en formato XML que indica en qué comercio prueba (o pruebas) para ejecutar, así como qué otros módulos ejecutar y en qué en el orden personalizado.
Creemos una nueva configuración para HelloWorldTest (ten en cuenta que la clase completa nombre de HelloWorldTest):
<configuration description="Runs the hello world test"> <test class="com.android.tradefed.example.HelloWorldTest" /> </configuration>
Guarda estos datos en un archivo helloworld.xml
en cualquier parte de tu entorno local.
un sistema de archivos (por ejemplo, /tmp/helloworld.xml
). TF analizará los
Archivo de configuración en formato XML (también conocido como config), carga la clase especificada usando
reflejo, crea una instancia, transmítela a un objeto IRemoteTest
y llama a su
run
.
Ejecuta la configuración (R)
Desde tu shell, inicia la consola de intercambio:
tradefed.sh
Asegúrate de que un dispositivo esté conectado a la máquina anfitrión y sea visible para el intercambio:
tf> list devices Serial State Product Variant Build Battery 004ad9880810a548 Available mako mako JDQ39 100
Las configuraciones se pueden ejecutar con run <config>
.
Comando de la consola. Prueba lo siguiente:
tf> run /tmp/helloworld.xml 05-12 13:19:36 I/TestInvocation: Starting invocation for target stub on build 0 on device 004ad9880810a548 Hello, TF World!
Deberías ver “Hello, TF World!” de salida en la terminal.
Puedes confirmar que se termine de ejecutar un comando con list invocations
.
l i
en el mensaje de la consola, y no debería imprimir nada. Si los comandos están actualmente
en ejecución, se muestran de la siguiente manera:
tf >l i Command Id Exec Time Device State 10 0m:00 [876X00GNG] running stub on build(s) 'BuildInfo{bid=0, target=stub, serial=876X00GNG}'
Agrega la configuración a la ruta de clase (D, I, R)
Para mayor comodidad de la implementación, también puedes agrupar los parámetros de configuración en la distribución JAR en sí. Tradefed reconoce automáticamente todas las configuraciones config en la ruta de clase.
A modo de ejemplo, mueve el archivo helloworld.xml
al objeto Tradefed
biblioteca principal
(<tree>/tools/tradefederation/core/res/config/example/helloworld.xml
)
Vuelve a compilar el intercambio, reinicia la consola del intercambio y pídele al intercambio que muestre el
de configuración de la ruta de clase:
tf> list configs […] example/helloworld: Runs the hello world test
Ahora puedes ejecutar la configuración de helloworld con el siguiente comando:
tf> run example/helloworld 05-12 13:21:21 I/TestInvocation: Starting invocation for target stub on build 0 on device 004ad9880810a548 Hello, TF World!
Interactuar con un dispositivo (D, R)
Hasta ahora, HelloWorldTest no está haciendo nada interesante. Tradefed especializada es ejecutar pruebas con dispositivos Android, así que agreguemos un dispositivo Android. a prueba.
Las pruebas pueden obtener una referencia a un dispositivo Android usando TestInformation
, proporcionado
por el framework cuando se llama al método IRemoteTest#run
.
Modifiquemos el mensaje de impresión HelloWorldTest para mostrar el número de serie de el dispositivo:
@Override public void run(TestInformation testInfo, ITestInvocationListener listener) throws DeviceNotAvailableException { CLog.i("Hello, TF World! I have device " + testInfo.getDevice().getSerialNumber()); }
Ahora, vuelve a compilar el canal de Exchange y revisa la lista de dispositivos:
tradefed.sh
tf> list devices Serial State Product Variant Build Battery 004ad9880810a548 Available mako mako JDQ39 100
Anota el número de serie que aparece como Available. es decir, el dispositivo que debería asignarse a HelloWorld:
tf> run example/helloworld 05-12 13:26:18 I/TestInvocation: Starting invocation for target stub on build 0 on device 004ad9880810a548 Hello, TF World! I have device 004ad9880810a548
Deberías ver el nuevo mensaje de impresión con el número de serie del dispositivo.
Enviar los resultados de la prueba (D)
IRemoteTest
informa los resultados llamando a los métodos en el
ITestInvocationListener.
proporcionada al método #run
. El framework de TF en sí es
responsable de informar el inicio (mediante
ITestInvocationListener#invocationStarted)
y finalizan (mediante
ITestInvocationListener#invocationEnded)
de cada Invocación.
Una ejecución de pruebas es una colección lógica de pruebas. Para informar los resultados de las pruebas, sigue estos pasos:
IRemoteTest
es responsable de informar el inicio de una ejecución de prueba.
el inicio y el final de cada prueba y el final de su ejecución.
Así es como se vería la implementación de HelloWorldTest con un solo resultado fallido de la prueba.
@Override public void run(TestInformation testInfo, ITestInvocationListener listener) throws DeviceNotAvailableException { CLog.i("Hello, TF World! I have device " + testInfo.getDevice().getSerialNumber()); TestDescription testId = new TestDescription("com.example.TestClassName", "sampleTest"); listener.testRunStarted("helloworldrun", 1); listener.testStarted(testId); listener.testFailed(testId, "oh noes, test failed"); listener.testEnded(testId, Collections.emptyMap()); listener.testRunEnded(0, Collections.emptyMap()); }
TF incluye varias implementaciones de IRemoteTest
que puedes reutilizar
en lugar de escribir la tuya desde cero. Por ejemplo:
Prueba de instrumentación
puede ejecutar las pruebas de una aplicación para Android de forma remota en un dispositivo Android, analizar la
y reenviar esos resultados a ITestInvocationListener
).
Para obtener más información, consulta
Probar
Tipos.
Almacenar los resultados de la prueba (I)
La implementación predeterminada del objeto de escucha de prueba para una configuración de TF es TextResultReporter que que vuelca los resultados de una invocación en stdout. A modo de ejemplo, ejecuta el Configuración de HelloWorldTest de la sección anterior:
./tradefed.sh
tf> run example/helloworld 04-29 18:25:55 I/TestInvocation: Invocation was started with cmd: /tmp/helloworld.xml 04-29 18:25:55 I/TestInvocation: Starting invocation for 'stub' with '[ BuildInfo{bid=0, target=stub, serial=876X00GNG} on device '876X00GNG'] 04-29 18:25:55 I/HelloWorldTest: Hello, TF World! I have device 876X00GNG 04-29 18:25:55 I/InvocationToJUnitResultForwarder: Running helloworldrun: 1 tests 04-29 18:25:55 W/InvocationToJUnitResultForwarder: Test com.example.TestClassName#sampleTest failed with stack: oh noes, test failed 04-29 18:25:55 I/InvocationToJUnitResultForwarder: Run ended in 0 ms
Para almacenar los resultados de una invocación en otro lugar, como en un archivo, especifica un
implementación personalizada de ITestInvocationListener
con el
result_reporter
en tu configuración.
TF también incluye la
XmlResultReporter.
de objetos de escucha, que escribe los resultados de la prueba en un archivo XML en un formato similar al
que usa el escritor XML ant JUnit. Para especificar result_reporter en la
de Terraform, edita el …/res/config/example/helloworld.xml
configuración:
<configuration description="Runs the hello world test"> <test class="com.android.tradefed.example.HelloWorldTest" /> <result_reporter class="com.android.tradefed.result.XmlResultReporter" /> </configuration>
Ahora, vuelve a compilar el protocolo Tradefed y ejecuta nuevamente la muestra de Hello World:
tf> run example/helloworld 05-16 21:07:07 I/TestInvocation: Starting invocation for target stub on build 0 on device 004ad9880810a548 Hello, TF World! I have device 004ad9880810a548 05-16 21:07:07 I/XmlResultReporter: Saved device_logcat log to /tmp/0/inv_2991649128735283633/device_logcat_6999997036887173857.txt 05-16 21:07:07 I/XmlResultReporter: Saved host_log log to /tmp/0/inv_2991649128735283633/host_log_6307746032218561704.txt 05-16 21:07:07 I/XmlResultReporter: XML test result file generated at /tmp/0/inv_2991649128735283633/test_result_536358148261684076.xml. Total tests 1, Failed 1, Error 0
Observa el mensaje de registro que indica que se generó un archivo en formato XML. el el archivo generado debería verse así:
<?xml version='1.0' encoding='UTF-8' ?> <testsuite name="stub" tests="1" failures="1" errors="0" time="9" timestamp="2011-05-17T04:07:07" hostname="localhost"> <properties /> <testcase name="sampleTest" classname="com.example.TestClassName" time="0"> <failure>oh noes, test failed </failure> </testcase> </testsuite>
También puedes escribir tus propios objetos de escucha de invocación personalizados; solo tienen que necesitas implementar el ITestInvocationListener. interfaz de usuario.
Tradefed admite varios objetos de escucha de invocación, por lo que puedes enviar resultados de prueba
a múltiples destinos independientes. Para ello, simplemente especifica varias
Etiquetas <result_reporter>
en tu configuración.
Instalaciones de registro (D, I, R)
Las utilidades de registro de TF incluyen la capacidad de realizar las siguientes acciones:
- Captura registros del dispositivo (también conocido como logcat de dispositivo)
- Registrar registros del marco de la Federación de Comercio que se ejecutan en la máquina anfitrión (también conocido como registro del host)
El framework de TF captura automáticamente el logcat del dispositivo asignado.
y lo envía al objeto de escucha de invocación para su procesamiento.
Luego, XmlResultReporter
guarda el logcat del dispositivo capturado como un archivo.
Los registros del host de TF se informan
Wrapper de CLog
para la clase de registro ddmlib. Vamos a convertir
llamada System.out.println
anterior en HelloWorldTest a un
Llamada de CLog
:
@Override public void run(ITestInvocationListener listener) throws DeviceNotAvailableException { CLog.i("Hello, TF World! I have device %s", getDevice().getSerialNumber());
CLog
controla la interpolación de cadenas directamente, de manera similar a
String.format
Cuando vuelvas a compilar y a ejecutar TF, deberías ver el
mensaje de registro en stdout:
tf> run example/helloworld … 05-16 21:30:46 I/HelloWorldTest: Hello, TF World! I have device 004ad9880810a548 …
De forma predeterminada,
resultados del registro del host
mensajes a stdout. TF también incluye una implementación de registros que escribe
mensajes a un archivo:
FileLogger
Para agregar un registro de archivos, agrega una etiqueta logger
a la configuración y especifica la
nombre completo de la clase de FileLogger
:
<configuration description="Runs the hello world test"> <test class="com.android.tradefed.example.HelloWorldTest" /> <result_reporter class="com.android.tradefed.result.XmlResultReporter" /> <logger class="com.android.tradefed.log.FileLogger" /> </configuration>
Ahora, vuelve a compilar y ejecuta el ejemplo de helloworld:
tf >run example/helloworld … 05-16 21:38:21 I/XmlResultReporter: Saved device_logcat log to /tmp/0/inv_6390011618174565918/device_logcat_1302097394309452308.txt 05-16 21:38:21 I/XmlResultReporter: Saved host_log log to /tmp/0/inv_6390011618174565918/host_log_4255420317120216614.txt …
El mensaje de registro indica la ruta del registro del host, que, cuando se visualiza, debe contener el mensaje de registro de HelloWorldTest:
more /tmp/0/inv_6390011618174565918/host_log_4255420317120216614.txt
Resultado de ejemplo:
… 05-16 21:38:21 I/HelloWorldTest: Hello, TF World! I have device 004ad9880810a548
Opciones de manejo (D, I, R)
Objetos cargados desde una configuración de TF (también conocida como objetos de configuración)
también puede recibir datos de argumentos de la línea de comandos
@Option
.
Para participar, una clase de objeto Configuration aplica el @Option
una anotación a un campo de miembro y le otorga un nombre único. Esto permite que
el valor del campo de miembro que se propagará con una opción de línea de comandos (y también
agrega automáticamente esa opción al sistema de ayuda de configuración).
Nota: No todos los tipos de campos son compatibles. Para un descripción de los tipos admitidos, consulta OptionSetter.
Agreguemos un @Option
a HelloWorldTest:
@Option(name="my_option", shortName='m', description="this is the option's help text", // always display this option in the default help text importance=Importance.ALWAYS) private String mMyOption = "thisisthedefault";
A continuación, agregaremos un mensaje de registro para mostrar el valor de la opción en HelloWorldTest para que podamos demostrar que se recibió correctamente:
@Override public void run(ITestInvocationListener listener) throws DeviceNotAvailableException { … CLog.logAndDisplay(LogLevel.INFO, "I received option '%s'", mMyOption);
Por último, vuelve a compilar TF y ejecuta helloworld. deberías ver un mensaje de registro
Valor predeterminado de my_option
:
tf> run example/helloworld … 05-24 18:30:05 I/HelloWorldTest: I received option 'thisisthedefault'
Pasa valores desde la línea de comandos
Pasa un valor para my_option
. deberías ver
my_option
propagado con ese valor:
tf> run example/helloworld --my_option foo … 05-24 18:33:44 I/HelloWorldTest: I received option 'foo'
Los parámetros de configuración de TF también incluyen un sistema de ayuda, que muestra automáticamente
texto de ayuda para @Option
campos. Pruébalo ahora. Deberías ver el
Texto de ayuda para my_option
:
tf> run example/helloworld --help Printing help for only the important options. To see help for all options, use the --help-all flag cmd_options options: --[no-]help display the help text for the most important/critical options. Default: false. --[no-]help-all display the full help text for all options. Default: false. --[no-]loop keep running continuously. Default: false. test options: -m, --my_option this is the option's help text Default: thisisthedefault. 'file' logger options: --log-level-display the minimum log level to display on stdout. Must be one of verbose, debug, info, warn, error, assert. Default: error.
Observa el mensaje "imprimir solo las opciones importantes". Para reducir
opción ayuda a desordenar, TF usa el atributo Option#importance
para
determinar si se muestra un texto de ayuda del campo @Option
en particular cuando
Se especifica --help
. --help-all
siempre muestra ayuda para
todos los campos @Option
, independientemente de la importancia. Para obtener más información, consulta
Opción.Importancia.
Cómo pasar valores de una configuración
También puedes especificar un valor de opción en la configuración agregando un
<option name="" value="">
. Pruébalo con
helloworld.xml
:
<test class="com.android.tradefed.example.HelloWorldTest" > <option name="my_option" value="fromxml" /> </test>
Si vuelves a compilar y ejecutar helloworld, ahora se debería producir el siguiente resultado:
05-24 20:38:25 I/HelloWorldTest: I received option 'fromxml'
La ayuda de configuración también debe actualizarse para indicar el valor predeterminado de
my_option
:
tf> run example/helloworld --help test options: -m, --my_option this is the option's help text Default: fromxml.
Otros objetos de configuración incluidos en la configuración de helloworld, como
FileLogger
, también acepta opciones. La opción
--log-level-display
es interesante porque filtra los registros que
aparecer en stdout. Anteriormente en el instructivo, quizás hayas notado el mensaje “Hello, TF
¡Mundial! Tengo dispositivo... el mensaje de registro dejó de mostrarse en stdout después de que
pasó a usar FileLogger
. Puedes aumentar la verbosidad de
registro en stdout pasando el argumento --log-level-display
Pruébalo ahora. Deberías ver el mensaje “Tengo dispositivo” los mensajes de registro volverán a aparecer en stdout, además de registrarse en un archivo:
tf> run example/helloworld --log-level-display info … 05-24 18:53:50 I/HelloWorldTest: Hello, TF World! I have device 004ad9880810a548
¡Eso es todo, amigos!
Como recordatorio, si estás atascado en algo, el Comercio El código fuente de federación tiene mucha información útil que no se expone en la documentación. Si todo lo demás falla, intenta preguntar en el plataforma-android Grupo de Google con la "Federación de Comercio" en el asunto del mensaje.