jueves, 31 de julio de 2014

Testing automatico con Robotium

¿Que es Robotium? ¿como se usa? ejemplos.
Robotium es un framework creado para implementar test automáticos de aplicaciones Android. Con esta herramienta se puede testear cualquier tipo de aplicación visual como Activities o Dialogs. Asemejandolo con el mundo del desarrollo web, se podría decir que Robotium es el Selenium de Android.
La dinámica de trabajo con este framework es la programación de acciones que simulan al usuario. Por ejemplo, se puede realizar la acción de realizar click en un texto especificado, introducir un texto en una caja de entrada concreta o busca un texto en el propio formulario. Realizando varias de estas acciones se puede comprobar si hay un texto de salida mediante un Assert y de esta forma validar si la aplicación funciona bien y pasa el test.
Un ejemplo de código en el test sería el siguiente:
solo.sendKey(Solo.MENU);
solo.clickOnText("Archivo");
solo.clickOnText("Nuevo");
Assert.assertTrue(solo.searchText("Crear nueva ficha"));
Entonces, en este Workshop vamos a probar este framework aquí comento los pasos a realizar:
  • Instalar las herramientas que ofrece y recomienda Google: Eclipse, ADT (Android Develepment Tools), SDK (Software Development Kit) y JDK (Java).
  • Descargar el archivo robotium-solo-(version).jar que contiene el framework.
  • Será necesario que tengan un proyecto Android con la aplicación que deseas testear.
  • Crear un proyecto de Test Android: Pulsar File->New->Project->Android->Android Test Project.
  • Añadir el archivo jar al proyecto: Pulsar en el proyecto->Build path->Configure Build Path y añadir el jar de Robotium.
  • Modificar el fichero AndroidManifest.xml y cambiar en el atributo targetPackage de ApplicationTesting a ApplicationToTest.
  • Crear un test de ejemplo: Pulsar New->Class, derivar esta clase de ActivityInstrumentationTestCase2 e implementar los test que se deseen.
  • Para probarlo es necesario que el archivo apk tenga el mismo certificado que el proyecto de test. Para esto será recomendable darle un vistazo a la firma de aplicaciones del manual de android.
  • Finalmente ejecutar los test: Pulsar en el proyecto Run As>Android JUnit Test.
Como todos los test automáticos del interface visual, tienen problemas con la estabilidad del propio test. El principal problema que nos podemos encontrar es con la modificación del propio interface, algo habitual cuando se está desarrollando y diseñando la aplicación. Si ocurriese alguna modificación en algún texto, los test afectados se deberían cambiar modificandolos a los nuevos literales.
Al igual que otros test automáticos se puede utilizar con Maven o Ant para integrar las pruebas en algún servidor de integración continua como Jenkins y de esta forma calcular los resultados de los test de manera automática para tenerlos siempre a disposición del equipo. La licencia de este framework es Apache 2.0 y actualmente se encuentra por la versión 5.2.1. Una herramienta interesante para aquellos apasionados del testing y de Android.

Link de descarga | Robotium

miércoles, 30 de julio de 2014

Genymotion, como te quiero!

Genymotion

¿Que es este emulador? ¿como se usa? ¿que ventajas tengo?
Genymotion es un emulador de Android que aprovecha la arquitectura x86 para ejecutar de forma fluida y rápida distintos dispositivos Android. Olvidando la lentitud del emulador nativo de Android podemos ejecutar todo tipo de aplicaciones y juegos en nuestro Windows, Mac o Linux.
Uno de los principales usos de Genymotion es facilitar el desarrollo de aplicaciones Android. Casi más de 900.000 usuarios registrados usan sus maquinas virtuales para crear aplicaciones usando Eclipse o intelliJ. Se integran perfectamente con el adb, línea de comandos y los diferentes entorno de desarrollo. Podemos lanzar en apenas un par de segundos las aplicaciones conectadas al ADT desde el IDE para testearla. Mucho tiempo ahorrado.
Genymotion está basado en el uso de máquinas virtuales x86 optimizadas para correr sobre Virtualbox. A muchos les sonarán proyectos similares, pero la gente de Genymotion ha conseguido crear una interfaz simple capaz de soportar distintas funcionalidades accesibles a cualquier usuario, sin olvidar a los desarrolladores (su principal target y modelo de negocio).
Imagenes x86 Genymotion
Al descargar Genymotion podemos instalar, en apenas un par de clicks, cualquiera de las máquinas virtuales que emulan dispositivos como Nexus 4, Nexus 5, Nexus 7, Galaxy Nexus, HTC One, Moto X, Galaxy S4, Xperia Z, etc… para distintas configuraciones de Android 2.3, 4.1, 4.2, 4.3 y 4.4 , además de diferentes resoluciones de pantalla. El número de máquinas va aumentando según se van creando configuraciones personalizadas.
Entre todas de las características que aporta el emulador de Genymotion se encuentran el uso de nuestra conexión a internet, la simulación ubicaciones GPS con el widgets que facilita la búsqueda y el posicionamiento sobre un mapa, simulación de la cámara, estado de la batería, rotación del dispositivo, etc.. También ofrecen cuentas premium que incluyen el control remoto táctil desde otro dispositivo, Pixel perfect para diseñar tal cual se vería en el dispositivo o la grabación de screencast desde la interfaz.
Por problemas de licencia, Genymotion no incluyen por defecto la aplicaciones de Google, aunque está trabajando para conseguir un acuerdo de Google. Aunque no hay problema, ya que Genymotion permite instalar cualquier apk o zip arrastrando sobre el emulador el archivo. Así que podemos echar un vistazo a los zip de Google Apps de rooztwiki e instalar el compatible con nuestro dispositivo. Perfecto.

Más información | Genymotion

lunes, 28 de julio de 2014

Maven en Android

Navegando en la web, encontrè un gran trabajo de la gente de "Adictos al Trabajo", y como una linda forma de recomendarlos, vamos a repasar esta importante herramienta llamada Maven, y como la utilizamos en el desarollo Android, tomando como base el documento creado por ellos.
Fuente de los ejemplos, codigo y texto:

Trabajaremos con un plugin llamado "maven-android-plugin" que nos permite crear proyectos Maven específicos para Android. Toda la información relativa a este plugin la podéis encontrar aquí.
Nos proporciona comandos específicos de Maven para lanzar el emulador, desplegar la aplicación en todos los dispositivos conectados, arrancar la aplicación y eliminar la aplicación; y sobre todo poder integrar el proyecto fácilmente en nuestro proceso de integración continua.

Creación del proyecto

Lo primero que vamos a hacer es crear el proyecto Maven con el arquetipo de Android que nos ofrecen. Para ello abrimos un terminal, nos situamos en el directorio donde queramos crear el proyecto y ejecutamos:
mvn archetype:generate -DarchetypeArtifactId=android-quickstart -DarchetypeGroupId=de.akquinet.android.archetypes     
-DarchetypeVersion=1.0.8 -DgroupId=com.autentia -DartifactId=calc-android -Dversion=1.0-SNAPSHOT  

Para ilustrar el ejemplo vamos a hacer una calculadora. Ahora abrimos Eclipse e importamos el proyecto como proyecto de Maven. Si el Eclipse está bien configurado debería detectar el proyecto como un proyecto gestionado por Maven de Android. Para saberlo basta con que pinchemos con el botón derecho sobre la raíz del proyecto y ver que en la sección "Run As" aparece la opción "Android Application".
Si abrimos el fichero pom.xml que nos ha generado, vemos que a parte de las dependencias necesarias, ya tenemos declarado el plugin "maven-android-plugin" con una configuración por defecto.
<plugin>  
  1.    <groupid>com.jayway.maven.plugins.android.generation2</groupid>  
  2.    <artifactid>android-maven-plugin</artifactid>  
  3.    <version>3.1.1</version>  
  4.    <configuration>  
  5.        <androidmanifestfile>${project.basedir}/AndroidManifest.xml</androidmanifestfile>  
  6.        <assetsdirectory>${project.basedir}/assets</assetsdirectory>  
  7.        <resourcedirectory>${project.basedir}/res</resourcedirectory>  
  8.        <nativelibrariesdirectory>${project.basedir}/src/main/native</nativelibrariesdirectory>  
  9.        <sdk>  
  10.            <platform>10</platform>  
  11.        </sdk>  
  12.        <undeploybeforedeploy>true</undeploybeforedeploy>  
  13.    </configuration>  
  14.    <extensions>true</extensions>  
  15. </plugin>  
La configuración viene por defecto para la plataforma 10 de Android que se corresponde con la versión 2.3.3 de Android. Por lo que nos vamos a asegurar de tener un emulador compatible creado en el SDK. En caso contrario, lo podemos hacer desde Eclipse, simplemente abriendo el "Android Virtual Device (AVD) Manager" desde la opción Window del menú de Eclipse.
Para crear una nueva instancia pulsamos en "New", establecemos un nombre para el dispositivo (AVD-2.3.3-10), seleccionamos una plataforma objetivo, en este caso Api Level 10 y el resto de opciones las dejamos por defecto.
Para establecer este dispositivo como predeterminado a la hora de lanzar el emulador con el plugin de Maven tenemos que dejar la configuración de esta forma:
  1. <plugin>  
  2.    <groupid>com.jayway.maven.plugins.android.generation2</groupid>  
  3.    <artifactid>android-maven-plugin</artifactid>  
  4.    <version>3.1.1</version>  
  5.    <configuration>  
  6.        <androidmanifestfile>${project.basedir}/AndroidManifest.xml</androidmanifestfile>  
  7.        <assetsdirectory>${project.basedir}/assets</assetsdirectory>  
  8.        <resourcedirectory>${project.basedir}/res</resourcedirectory>  
  9.        <nativelibrariesdirectory>${project.basedir}/src/main/native</nativelibrariesdirectory>  
  10.        <sdk>  
  11.            <platform>10</platform>  
  12.        </sdk>  
  13.        <undeploybeforedeploy>true</undeploybeforedeploy>  
  14.        <emulator>  
  15.            <avd>AVD-2.3.3-10</avd>  
  16.        </emulator>  
  17.    </configuration>  
  18.    <extensions>true</extensions>  
  19. </plugin>  

Creamos la lógica de negocio

En este caso simple, la lógica de negocio va a consistir en una calculadora que contenga los típicos métodos de suma, resta, multiplicación y división. Como no puede ser de otra forma la implementación de la lógica de negocio la comenzados con un test el cual no irá descubriendo el diseño de nuestra solución. Para ello necesitamos incluir la dependencia JUnit en el pom.xml del proyecto. Después de todos los ciclos de TDD necesarios, este es el código del test resultante.
  1. package com.autentia.logic;  
  2.  
  3. import org.junit.Assert;  
  4. import org.junit.Test;  
  5.  
  6. public class CalculadoraTest {  
  7.      
  8.    @Test  
  9.    public void addTwoOperands(){  
  10.        Double op1 = Double.valueOf(3.0);  
  11.        Double op2 = Double.valueOf(4.0);  
  12.          
  13.        Assert.assertEquals(Double.valueOf(7.0), Calculadora.add(op1, op2));  
  14.          
  15.    }  
  16.      
  17.    @Test  
  18.    public void sustractTwoOperands(){  
  19.        Double op1 = Double.valueOf(5.0);  
  20.        Double op2 = Double.valueOf(2.0);  
  21.          
  22.        Assert.assertEquals(Double.valueOf(3.0), Calculadora.sustract(op1, op2));  
  23.    }  
  24.      
  25.    @Test  
  26.    public void multiplyTwoOperands(){  
  27.        Double op1 = Double.valueOf(6.0);  
  28.        Double op2 = Double.valueOf(2.0);  
  29.          
  30.        Assert.assertEquals(Double.valueOf(12.0), Calculadora.multiply(op1, op2));  
  31.    }  
  32.      
  33.    @Test  
  34.    public void divideTwoOperands(){  
  35.        Double op1 = Double.valueOf(10.0);  
  36.        Double op2 = Double.valueOf(2.0);  
  37.          
  38.        Assert.assertEquals(Double.valueOf(5.0), Calculadora.divide(op1, op2));  
  39.    }  
  40. }  
Y el código resultante para la clase Calculadora
  1. package com.autentia.logic;  
  2.  
  3. public class Calculadora {  
  4.  
  5.    public static Double add(Double op1, Double op2) {  
  6.        return op1 + op2;  
  7.    }  
  8.  
  9.    public static Double sustract(Double op1, Double op2) {  
  10.        return op1 - op2;  
  11.    }  
  12.      
  13.    public static Double multiply(Double op1, Double op2) {  
  14.        return op1 * op2;  
  15.    }  
  16.      
  17.    public static Double divide(Double op1, Double op2) {  
  18.        return op1 / op2;  
  19.    }  
  20. }  

5. Definición de la interfaz de usuario

Ahora vamos a crear la pantalla que permita al usuario introducir los dos operandos y seleccionar la operación a realizar. Para ello, editamos el fichero res/layout/main.xml que nos ha creado el plugin con un contenido por defecto.
Utilizando el "Graphical Layout" de Eclipse creamos visualmente la interfaz deseada que se podría parecer a la que se muestra a continuación.
La interfaz es claramente mejorable pero para el propósito de este tutorial es suficiente. Tenemos que tener presente los ids que le damos a los distintos elementos, en mi caso:
  • Campo de texto 'Operando 1': strOp1
  • Campo de texto 'Operando 2': strOp2
  • Botón de sumar: btnAdd
  • Botón de restar: btnSustract
  • Botón de multiplicar: btnMultiply
  • Botón de dividir: btnDivide
  • Etiqueta de 'Resultado': txtResult
Tendremos que tener en cuenta estos ids a la hora de interactuar con el interfaz gráfico desde la actividad.

6. Creamos la actividad

Toda aplicación de Android necesita al menos de una actividad; por lo que nosotros vamos a renombrar la actividad que el plugin te crea por defecto 'HelloAndroidActivity' por 'CaclActivity'. No olvidéis cambiar el nombre también en la declaración de la actividad dentro del fichero AndroidManifest.xml.
Ahora vamos a incluir los manejadores de los eventos cuando pulsamos algún botón de operación y un manejador para borrar el resultado cuando se pulse encima del campo de texto. El código resultante de la actividad sería:
  1. package com.autentia;  
  2.  
  3. import com.autentia.logic.Calculadora;  
  4.  
  5. import android.app.Activity;  
  6. import android.os.Bundle;  
  7. import android.util.Log;  
  8. import android.view.View;  
  9. import android.widget.Button;  
  10. import android.widget.EditText;  
  11. import android.widget.TextView;  
  12.  
  13. public class CalcActivity extends Activity {  
  14.  
  15.    private static String TAG = "calc-android";  
  16.  
  17.    @Override  
  18.    public void onCreate(Bundle savedInstanceState) {  
  19.        super.onCreate(savedInstanceState);  
  20.        Log.i(TAG, "onCreate");  
  21.        setContentView(R.layout.main);  
  22.          
  23.        //Cuando el usuario pulsa el campo de texto Resultado se borra el contenido  
  24.        final TextView txtResult = (TextView) findViewById(R.id.txtResult);  
  25.        txtResult.setOnClickListener(new EditText.OnClickListener() {  
  26.            public void onClick(View v) {  
  27.                txtResult.setText("");  
  28.            }  
  29.        });  
  30.  
  31.        //Cuando el usuario pulsa el botón Add se realiza la suma de los operandos  
  32.        final Button btnAdd = (Button) findViewById(R.id.btnAdd);  
  33.        btnAdd.setOnClickListener(new Button.OnClickListener() {  
  34.            public void onClick(View v) {  
  35.                Double[] operands = getOperandsInView();  
  36.                txtResult.setText(String.valueOf(Calculadora.add(operands[0], operands[1])));  
  37.            }  
  38.        });  
  39.          
  40.        //Cuando el usuario pulsa el botón Sustract se realiza la resta de los operandos  
  41.        final Button btnSustract = (Button) findViewById(R.id.btnSustract);  
  42.        btnSustract.setOnClickListener(new Button.OnClickListener() {  
  43.            public void onClick(View v) {  
  44.                Double[] operands = getOperandsInView();  
  45.                txtResult.setText(String.valueOf(Calculadora.sustract(operands[0], operands[1])));  
  46.            }  
  47.        });  
  48.          
  49.        //Cuando el usuario pulsa el botón Multiply se realiza la multiplicación de los operandos  
  50.        final Button btnMultiply = (Button) findViewById(R.id.btnMultiply);  
  51.        btnMultiply.setOnClickListener(new Button.OnClickListener() {  
  52.            public void onClick(View v) {  
  53.                Double[] operands = getOperandsInView();  
  54.                txtResult.setText(String.valueOf(Calculadora.multiply(operands[0], operands[1])));  
  55.            }  
  56.        });  
  57.          
  58.        //Cuando el usuario pulsa el botón Sustract se realiza la resta de los operandos  
  59.        final Button btnDivide = (Button) findViewById(R.id.btnDivide);  
  60.        btnDivide.setOnClickListener(new Button.OnClickListener() {  
  61.            public void onClick(View v) {  
  62.                Double[] operands = getOperandsInView();  
  63.                txtResult.setText(String.valueOf(Calculadora.divide(operands[0], operands[1])));  
  64.            }  
  65.        });  
  66.          
  67.    }  
  68.      
  69.    private Double[] getOperandsInView(){  
  70.        final String strOp1 = ((EditText) findViewById(R.id.strOp1)).getText().toString();  
  71.        final String strOp2 = ((EditText) findViewById(R.id.strOp2)).getText().toString();  
  72.  
  73.        Double op1 = Double.valueOf(0);  
  74.        if (!"".equals(strOp1)){  
  75.            op1 = Double.valueOf(strOp1);  
  76.        }  
  77.          
  78.        Double op2 = Double.valueOf(0);  
  79.        if (!"".equals(strOp2)){  
  80.            op2 = Double.valueOf(strOp2);  
  81.        }  
  82.          
  83.        Double[] operands =  new Double[2];  
  84.        operands[0] = op1;  
  85.        operands[1] = op2;  
  86.          
  87.        return operands;  
  88.          
  89.    }  
Ejecutamos un 'mvn clean install' del proyecto para ver que todo es correcto y para que nos genere el .apk que tenemos que instalar en el dispositivo móvil.

7. Probando la aplicación

Para probar la aplicación vamos a lanzar el emulador que creamos anteriormente. Para ello simplemente abrimos un terminal, nos situamos en el directorio raíz del proyecto y ejecutamos 'mvn android:emulator-start'. Pasados unos segundos el sistema nos mostrará el emulador con el que podremos interactuar como si de un móvil se tratase.
Ahora vamos a instalar el .apk del proyecto en el emulador o cualquier dispositivo que tengamos conectado. Para ello desde el terminal ejecutamos 'mvn android:deploy'. Una vez finalizado si accedemos a las aplicaciones del móvil debemos ver la nuestra. Ahora podemos ejecutar la aplicación directamente en el emulador o ejecutar desde línea de comandos 'mvn android:run' para poder interactuar con la aplicación.
Para eliminar la aplicación del dispositivo basta con ejecutar 'mvn android:undeploy'. En caso de querer actualizar alguna modificación en la aplicación podríamos ejecutar 'mvn android:redeploy' sin olvidar antes volver a ejecutar 'mvn clean install'.

Conclusiones


Maven es una importante herramienta de productividad que se utiliza en muchas empresas, es por eso que en este workshop presentamos un “HolaMundo” que nos permita saber como configurarlo en un proyecto.