Pruebas automatizadas
Las pruebas son una parte vital para asegurarnos que nuestra aplicación cumple con los requisitos, pero a medida que el proyecto va creciendo va dejando de ser eficaz ejecutar las pruebas manualmente desperdiciando así mucho tiempo que puede ser dedicado para otras cosas.Para las pruebas usaremos Ant, JUnit y Robotium.
En eclipse creamos un nuevo proyecto de pruebas, la creación y conceptos basicos estan explicados en estos dos articulos Testing from Eclipse with ADT y Testing Fundamentals
Ant
En este caso la única diferencia es que tenemos que indicarle a ant que esta vez el proyecto es un proyecto de pruebas.
android update test-project -m <main_path> -p <test_path>
Robotium
Robotium es un framework para la realización de pruebas en Android su uso facilita bastante las pruebas (sobre todo las relacionadas con UI). Para poder ejecutarlas en Jenkins sin problemas debemos colocar el jar de robotium en la carpeta libs/ del proyecto de pruebas y subirlo a nuestro repositorio.
Jenkins
La creación de la tarea es igual que la del articulo anterior, para obtener el código tenemos dos opciones obtenerlo directamente desde el repositorio o clonar el workspace de la tare de compilación. En mi caso voy a usar la segunda opción, ya que reduce el tiempo de ejecución y el consumo de ancho de banda. Para poder realizar la clonación tenemos que instalar Clone Workspace SCM Plugin, una vez instalado abrimos la tarea de compilación y en Post-build Actions agregamos la acción Archive for Clone Workspace SCM.
Luego en el proyecto de pruebas dentro de Source Code Management eligiremos Clone Workspace Parent Project y en lista desplegable elegimos el proyecto principal.
Luego en el proyecto de pruebas dentro de Source Code Management eligiremos Clone Workspace Parent Project y en lista desplegable elegimos el proyecto principal.
En Build Triggers hay que indicar que la tarea se iniciara al completarse la tarea anterior, en mi caso el nombre de esa tarea es Finder.
Emulador de Android
Cuando creamos un emulador mediante el SDK de Android, este por defecto se guarda en ~/.android/avd/. Por lo que si creamos un emulador con nuestro usuario este no podrá ser accedido por Jenkins ya que mirara en su home y no en el nuestro.
Lo mas simple es iniciar sesión con Jenkins y crear el emulador con el terminal con la instrucción android create avd. En la documentación podemos consultar con detalle todas las opciones de este comando.
Por ejemplo para crear un emulador con Froyo, ejecutaríamos
Lo mas simple es iniciar sesión con Jenkins y crear el emulador con el terminal con la instrucción android create avd. En la documentación podemos consultar con detalle todas las opciones de este comando.
Por ejemplo para crear un emulador con Froyo, ejecutaríamos
android avd create -n nombre -t android-8
Dependiendo de nuestra combinación HW+SW podemos encontrarnos con un error bastante molesto, al ejecutar el emulador con el usuario jenkins se generara un segmentation fault. Lo raro es que al ejecutarlo con nuestro usuario no hay ningún problema. Leyendo el informe del bug, podemos ver que se encontró un "workaround" para evitar el error, basta con renombrar la librería ANDROID_SDK/tools/lib/libOpenglRender.so. Al renombrar la librería el emulador no la encontrara por lo que hará el renderizado via software.
Build
Ya tenemos configurado el repositorio y el emulador ahora hay que definir que hacer en la compilación. Para eso agregaremos solo una instruccion en la seccion Build de Jenkins la cualr sera Invoke Ant tendremos que especificar el target como:
clean emma debug install test fetch-test-report
- clean: limpia el proyecto
- emma: indica que se analizara el code coverage
- debug: aplicacion en modo debug
- install: instala la aplicación en el emulador
- test: ejecuta las pruebas
- fetch-test-report: obtiene el resultado de las pruebas desde el emulador, lo definiremos mas adelante
Si tenemos las pruebas en el mismo repositorio que la aplicación tendremos que especificar que fichero build.xml usara ant ya que al buscar en la raíz encontrara el correspondiente a la aplicación y no al proyecto de pruebas. Para ello en el campo Build File ingresamos test/build.xml o la ruta donde se encuentren nuestro proyecto de pruebas.
Finalmente tendremos que definir dos propiedades en el campo Properties, la ruta del SDK y el target a usar
Finalmente tendremos que definir dos propiedades en el campo Properties, la ruta del SDK y el target a usar
sdk.dir=/opt/android-sdk-linux
target=android-8
Emma
Emma calculara el code coverage (cobertura de código) , lo cual es realmente útil para saber que partes de nuestro proyecto están cubiertas por las pruebas. Tendremos que instalar Emma Plugin en Jenkins y agregar en Post-build Action la acción Record Emma coverage report.Hay que indicar la ruta donde se encuentra el informe de cobertura, en nuestro caso sera en la carpeta bin del proyecto por lo que seria **/bin/coverage*.xml
En caso de que la ruta fuera distinta al ejecutar las pruebas con Emma en la consola de salida se muestra la ruta donde se guardan los informes bastaría con ver donde se guardan y modificar la ruta acorde a nuestro proyecto.
JUnit
Para poder mantener un registro de las pruebas realizadas y saber en detalle cuales fallaron y cuales no, Jenkins necesita el resultado de las pruebas en formato XML y ahi es cuando entra en juego Android JUnit report, bajamos el jar y lo agregamos a la carpeta libs/ del proyecto y lo subimos al repositorio.
Para configurarlo hay que hacer un par de cambios en nuestro proyecto primero nos vamos a AndroidManifest.xml, buscamos el tag instrumentation y cambiamos el atributo android:name
El segundo paso es crear el fichero custom_rules.xml en la carpeta raiz del proyectoPara configurarlo hay que hacer un par de cambios en nuestro proyecto primero nos vamos a AndroidManifest.xml, buscamos el tag instrumentation y cambiamos el atributo android:name
android:name="com.zutubi.android.junitreport.JUnitReportTestRunner"
Con esto estamos definiendo el target fetch-test-report el cual ejecutara el comando pull en adb para obtener el informe y lo guardara en reports/junit-report.xml.
A esta altura tenemos ant configurado para que obtenga el resultado de las pruebas desde el emulador, lo siguiente es añadir Publish JUnit test result report en Post-build Actions y definir donde encontrar el informe si no modificaron el custom_rules.xml anterior esta ruta seria **/tests/reports/junit-report.xml
Ya estamos listos para ejecutar la tarea, si todo sale bien en el dashboard del proyecto tendremos dos gráficos uno que nos indica el estado de las pruebas y otro el estado del code coverage. Tiene que ejecutarse al menos dos veces para poder ver la gráfica con datos. Al hacer click sobre las graficas se mostraran los detalles de cada informe.
Calidad del código
En esta parte nos centraremos en analizar la calidad de nuestro código, buscando código repetido, comprobando reglas de estilo y encontrando posibles bugs mediante análisis estadístico. Para esto crearemos nuevamente una tarea free-style. La configuración del repositorio y la compilación es igual que el proyecto de pruebas salvo que esta vez la compilación en vez la de ejecutarse al finalizar el proyecto principal se ejecutara al finalizar el proyecto de pruebas.
Nos quedaría definido el siguiente escenario: tenemos tareas, Finder, Finder-test y Finder-code-quality. Al hacer un commit se ejecuta la tarea Finder si no hay fallos se ejecuta Finder-test y nuevamente
Nos quedaría definido el siguiente escenario: tenemos tareas, Finder, Finder-test y Finder-code-quality. Al hacer un commit se ejecuta la tarea Finder si no hay fallos se ejecuta Finder-test y nuevamente
Build
Nuevamente a la hora de compilar lo único que haremos sera invocar a Ant. El target sera
findbugs pmd lint
FindBugs
FindBugs tal como su nombre indicara buscara bugs en nuestro código mediante análisis estadístico. Precisaremos el jar findbugs-ant el cual en mi caso no venia incluido en la versión de findbugs de Fedora así que lo baje e instale manualmente. Una vez bajado el archivo y descomprimido en /opt/findbugs-x.y.z donde x.y.z es la versión tendremos que copiar el archivo $FINDBUGS_HOME/lib/findbugs-ant.jar a $ANT_HOME/lib
Antes de ponernos a configurar FindBugs tendremos que instalar el plugin para Jenkins que nos mostrara el informe de manera detallada.
Tendremos que definir en ant el target findbugs, agregando el siguiente código al fichero custom_rules.xml sino existe lo creamos en la raíz de nuestro proyecto NO en el de pruebas.Antes de ponernos a configurar FindBugs tendremos que instalar el plugin para Jenkins que nos mostrara el informe de manera detallada.
El tag class indica donde se encontrar los archivos .class tenemos dos opciones forzar la compilación diciendo que el target findbugs depende de algún otro target que genere las clases (debug por ejemplo) mediante el atributo depends o usar las clases generadas por la tarea Finder, esta ultima opción es la que yo estoy usando. Por lo que ustedes tendrán que decidir que es lo que prefieren y adaptar la configuración de findbugs.
Al definir este target necesitaremos especificar el valor de algunas variables en el campo Properties de llamada a Ant.
findbugs.home=/opt/findbugs-2.0.1
android.jar=/opt/android-sdk-linux/platforms/android-8/android.jar
Tenemos que indicar la ruta del jar de Android como classpath auxiliar, es decir, es necesario para el analisis ya que se realizan llamadas a sus métodos en caso de no indicarlo cada vez que se haga una instancia de una clase de Android tendremos un error de missing class.
Y como ultimo paso para ejecutar y obtener los resultados de findbugs en Post-build Actions añadiremos Publish FindBugs analysis results y como ruta de los informes **/reports/findbugs.xml
Open Tasks
Con Open Tasks analizaremos nuestro código en búsqueda de tareas tipo TODO o FIXME, que muchas veces se añaden al código para indicar que falta algo por hacer o hay algo que arreglar y así permanecen durante la eternidad. Luego de instalar el plugin añadiendo Scan workspace for open tasks en Post-build Actions podremos configurar los parámetros de la búsqueda.
Como vemos en la imagen, tendremos que indicar que archivos queremos analizar, cuales excluir y los tags a buscar con su respectiva prioridad.
Como vemos en la imagen, tendremos que indicar que archivos queremos analizar, cuales excluir y los tags a buscar con su respectiva prioridad.
Checkstyle
El estilo del código también debe tenerse en cuenta a la hora de medir la calidad del mismo. Dependiendo del lenguaje con el que estemos trabajando tendremos un estilo definido para cada uno de ellos. Checkstyle se encargara de analizar este aspecto de nuestro código. Me encontré con el siguiente problema, lo mas raro es que si lo ejecutaba con mi usuario funcionaba sin problemas pero al ejecutarse mediante Jenkins daba ese error. Modificando ANT_HOME el problema se solucionaba parcialmente, ahora si lo ejecutaba con el usuario jenkins funcionaba, pero cuando era el propio Jenkins quien lo ejecutaba el error seguía ahí. La solución que encontré fue instalarlo desde el repositorio de Fedora.
Al igual que con findbugs, tendremos que definir el target para ant
No hay un fichero oficial para comprobar el estilo para Android, pero si que hay varios fichero por la vuelta, uno de ellos lo pueden encontrar en android-checkstyle.xml
PMD
PMD analizara el código en busca de posibles errores, variables sin usar, código muerto, demasiado complejo, duplicado, etc. Como siempre descargamos los binarios, y pasamos a agregar el target a Ant. Ya que CPD forma parte de PMD, no usaremos el informe de codigo duplicado ya que se encontrara dentro del informe de PMD.
Y mas de lo mismo, indicar en Post-build Actions que queremos publicar el informe generado por PMD.
Y finalmente tenemos todo listo, no es una tarea difícil pero si que puede ser bastante ardua. Sobre todo al principio si nunca habíamos usado Ant haciendo muchos cambios a base de prueba y error.
Y mas de lo mismo, indicar en Post-build Actions que queremos publicar el informe generado por PMD.
Y finalmente tenemos todo listo, no es una tarea difícil pero si que puede ser bastante ardua. Sobre todo al principio si nunca habíamos usado Ant haciendo muchos cambios a base de prueba y error.