viernes, 29 de noviembre de 2013

Como utilizar Robolectric y JUnit en AndroidStudio


El otro día en el trabajo, vi la necesidad de comenzar un proyecto Android, y tenía que ver cómo incorporar la librería Robolectric y JUnit para realizar los test del proyecto. Y como utilizo de IDE el Android Studio, vi que todavía no hay muchos tutoriales sobre este tema en español, así que me pareció bueno dejarlo plasmado en un post.  




Para poder utilizar esto, vamos a recibir la ayuda de Jake Wharton (responsable también de la librería ActionBarSherlock ) y a utilizar su plugin para Gradle, eso lo pueden encontrar acá :D
https://github.com/JakeWharton/gradle-android-test-plugin





Lo queden hacer entonces, será crear un proyecto Android con el Android Studio y modificar el archivo build.gradle para que les quede de una forma similar a esta:


buildscript {
    repositories {
        mavenCentral()
        maven {
            url 'https://oss.sonatype.org/content/repositories/snapshots/'
        }
    }
    dependencies {
        classpath 'com.android.tools.build:gradle:0.6.+'
        classpath 'com.squareup.gradle:gradle-android-test-plugin:0.9.1-SNAPSHOT'

    }
}
apply plugin: 'android'
apply plugin: 'android-test'

repositories {
    mavenCentral()
    maven {
            url 'https://oss.sonatype.org/content/repositories/snapshots/'
    }
}

android {
    compileSdkVersion 18
    buildToolsVersion "18.0.1"

    defaultConfig {
            minSdkVersion 15
            targetSdkVersion 19
    }

    buildTypes {

        release {
                runProguard true
                    proguardFile getDefaultProguardFile('proguard-android-optimize.txt')
            }
    }

    productFlavors {
            defaultFlavor {
                    proguardFile 'proguard-rules.txt'
            }
    }

    sourceSets {
            instrumentTest.setRoot('src/test')
    }
}

dependencies {

    testCompile 'junit:junit:4.10'
    testCompile 'org.robolectric:robolectric:2.1.+'
    testCompile 'com.squareup:fest-android:1.0.+'

    instrumentTestCompile 'junit:junit:4.10'
    instrumentTestCompile 'org.robolectric:robolectric:2.1.+'
    instrumentTestCompile 'com.squareup:fest-android:1.0.+'

}


Básicamente es agregar lo siguiente dentro de la sección buildscript:

maven {
            url 'https://oss.sonatype.org/content/repositories/snapshots/'

 
Y allí mismo en las dependencias:
classpath 'com.squareup.gradle:gradle-android-test-plugin:0.9.1-SNAPSHOT'

Después de eso agregamos el plugin con: apply plugin: 'android-test'

En la configuración de android, al final agregamos:

sourceSets {
            instrumentTest.setRoot('src/test')


 
Esto es para que Android Studio no busqué los test en la carpeta por defecto src/instrumentTest, y si lo haga en src/test

Y por último tenemos que agregar en nuestras dependencias las librerías que vamos a utilizar:

testCompile 'junit:junit:4.10'
testCompile 'org.robolectric:robolectric:2.1.+'
testCompile 'com.squareup:fest-android:1.0.+'

instrumentTestCompile 'junit:junit:4.10'
instrumentTestCompile 'org.robolectric:robolectric:2.1.+'
instrumentTestCompile 'com.squareup:fest-android:1.0.+'



Ya con eso, solo nos queda crear en la raíz de nuestro proyecto, dentro de la carpeta src, una llamada test, dentro de ella una java, para que quede de esta forma:




Casi por último sincronizamos el proyecto con gradle lo que nos va a descargar las librerías. Una vez que tengamos esto, para poder utilizar el framework Robolectric debemos agregar en cualquier parte de esa carpeta (test/java) una clase como esta:


import org.junit.runners.model.InitializationError;
import org.robolectric.AndroidManifest;
import org.robolectric.RobolectricTestRunner;
import org.robolectric.annotation.Config;
import org.robolectric.res.Fs;

public class RobolectricGradleTestRunner extends RobolectricTestRunner {
    public RobolectricGradleTestRunner(Class<?> testClass) throws InitializationError {
        super(testClass);
    }

    @Override protected AndroidManifest getAppManifest(Config config) {
        String manifestProperty = System.getProperty("android.manifest");
        if (config.manifest().equals(Config.DEFAULT) && manifestProperty != null) {
            String resProperty = System.getProperty("android.resources");
            String assetsProperty = System.getProperty("android.assets");
            return new AndroidManifest(Fs.fileFromPath(manifestProperty), Fs.fileFromPath(resProperty),
                    Fs.fileFromPath(assetsProperty));
        }
        return super.getAppManifest(config);
    }
}


Ya con eso habremos terminado, ya podemos escribir nuestros test (siempre dentro del árbol de directorio bajo test/java ), este es un pequeño ejemplo de ello.

import org.junit.Test;
import org.junit.runner.RunWith;

import static org.junit.Assert.assertTrue;

@RunWith(RobolectricGradleTestRunner.class)
public class pruebaTest {

    @Test
    public void probandoTest(){
        assertTrue(true);
    }
}


Para correr los test solo necesitamos abrir la terminal dentro de la carpeta de nuestro proyecto y ejecutamos ./gradlew test (puede que la primera vez necesites darle permisos de ejecución al archivo con chmod +x gradlew) Si los test corren correctamente nos dira que BUILD SUCCESSFUL ;) en caso contrario (pueden probarlo colocando false en el anterior test) les mostrará el siguiente mensaje:
There were failing tests. See the report at:
Y una dirección de archivo, si lo colocan en un navegador web, podrán ver el informe de error y log de porque sucedió el mismo;)

Para trabajar y poder correr algunos test más interesante podrían hacer cosas como estas:


// Crear una activity
@Before
public void setup() {
    activity = Robolectric.buildActivity(MainActivity.class).get();
}

// comprobamos que no sean null las referencias que vamos a usar
@Test
public void noDebeSerNull() {
  assertThat(activity).isNotNull();

  TextView textView = (TextView) activity.findViewById(R.id.textView);
  assertThat(textView).isNotNull();

  Button button = (Button) activity.findViewById(R.id.button);
  assertThat(button).isNotNull();

  EditText editText = (EditText) activity.findViewById(R.id.editText);
  assertThat(editText).isNotNull();
}

// para luego poder comprobar cosas como esta
@Test
public void AccionAlPresionarBoton() {
  TextView textView = (TextView) activity.findViewById(R.id.textView);
  Button button = (Button) activity.findViewById(R.id.button);
  EditText editText = (EditText) activity.findViewById(R.id.editText);

  editText.setText("Hola");

  button.performClick();

  assertThat(textView).containsText("Hola, como estas?");
}


Espero que les sirva, creo que es una interesante forma de poder trabajar con el Android Studio, nos vemos en la próxima ;) 


P.D: Acá les dejo un ejemplo completo de un archivo de configuración gradle:
Gist: Archivo de configuración

Saludos a todos, Gabriel

jueves, 28 de noviembre de 2013

Script para el sorteo de remeras del ultimo GDG Rosario

Hola a todos, este post en realidad es una pavada que quería compartir :D
Para la última reunión del GDG Rosario, repartimos algunas remeras, y previo a eso no teníamos una forma de repartirlas de manera igualitaria, pensamos en un sorteo, pero no teníamos mucho tiempo ni números ni nada. Solo la lista de personas que se habían anotado en el formulario de inscripción. Por eso decidí armar un pequeño script en Python, así que lo comparto por si a alguno le sirve ;)




#!/usr/bin/env python
# -*- coding: utf-8 -*-
import random
import sys

listaDeNombres = ['Daniel King', 'Santiago Mazzucchelli', 'Mauro Zadunaisky', 'Victor Pezzetti','Cristian Tsakim','Bruno Piaggio','Sergio Gómez', 'Pablo Sanfilippo', 'Antonio Roman Lauriano', 'Esteban de la Peña', 'I. Nadir    Palacios', 'Sebastián Baskovich','Marisol Opreni', 'juan ignacio paccapelo', 'yoel pruss', 'Juan Manuel    Rodriguez Guerrero','Roger Alcivar', 'Matias Antola', 'German Andino', 'Erica Mendez', 'Miguel Angel Vides', 'Sebastián Vansteenkiste', 'Magali Kain', 'Aldo Ortiz', 'Fernando Uranga']


random.shuffle(listaDeNombres)

raw_input("Comenzamos el sorteo en el GDGRosario\n")


while True:
    if not listaDeNombres:
           print "\nSe finalizó la lista para el sorteo"
           sys.exit()


    print 'Ganador ' + listaDeNombres.pop()
   
    if listaDeNombres:
           raw_input("\nContinuamos el sorteo... \n")


Era solamente para eso, en este caso la lista de nombres la agregamos en el mismo fuente, porque eran pocas personas, para la próxima seguro lo mejoro un poco, y me molesto de tomarlo del mismo archivo de inscripción :D Espero que les sirva ;)

Saludos a todos, Gabriel

jueves, 21 de noviembre de 2013

Como puedo usar el logcat para ayudarme al debug de mi aplicación?

Hola a todos, como están en este pequeño post, voy a tratar un tema que le trae problemas normalmente al que recién comienza a desarrollar con Android. El mismo es como utilizar los logs para poder realizar un debug y hasta para poder preguntar en foros y lista de correo. Ya que la mejor forma de que te ayuden a resolver tu problema es que les muestres una salida del logcat correcta y con bastante información de lo que le sucede a la aplicación en el momento del error o del funcionamiento inapropiado de la misma (ya que no siempre son errores :D )



Para poder hacer esto vamos a utilizar el logcat y la clase Log que nos provee el mismo SDK de Android, no digo que esta forma sea la mejor, pero creo que es una medianamente correcta y que les ayudara bastante si no saben utilizarlo, voy a poner un ejemplo de código:

Supongamos que tenemos una función llamada inputStreamToString donde realizamos un catch, y en muchos casos veo que para eso realizan algo similar a esto:

 catch (IOException e) {
        // e.printStackTrace();
        Toast.makeText(getApplicationContext(),
          "Error..." + e.toString(), Toast.LENGTH_LONG).show();
       }

En vez de eso, lo correcto podría ser utilizar el logcat así:

catch (IOException e) {
    Log.e(TAG, "Error inputStreamToString " + e);  
}

Deben notar que utilizó Log.e, eso es porque se trata de un error, para debug podría ser Log.d, u otro tipo de salida, esto es útil para que el logcat te coloree de forma diferentes la salida, y sea más fácil poder seguirlo ;)

Dónde TAG debe ser un string, si ven el código fuente de Android normalmente este contiene la string del nombre de la clase, por ejemplo:

private static final String TAG = "Activity";


Para más referencias, la documentación oficial:

Esa forma de usarlo es buena para ver el logcat y saber de donde vienen los errores o filtrar por clases a los logs ;)

Ahora lo que deberían hacer, es usar logs en su código fuente :D por ejemplo: Log.d(TAG, "Datos que caen al listview " + datos); otro ejemplo Log.d(TAG, "Datos que tomo del webservice " + datos);

En resumen, el logcat no es solamente para ver errores, sino para saber qué datos toma del medio que sea, pasa tu aplicación de un lado a otro, o para ver cualquier información que creas que te resulte necesaria para entender qué le sucede a tu aplicación y así poder corregir tu código.

Este post a sido corto, más que nada es un tip para que les resulte más sencillo encontrar y así poder corregir los errores en sus aplicaciones, además de poder consultarles a otras personas y que están puedan ayudarlos. Espero que les allá sido de utilidad.

Saludos, Gabriel


martes, 5 de noviembre de 2013

The Original Hacker primera edición !!!

Hola a todos como están? Nuevamente escribiendo un post, pero este será un poco diferente a lo que estoy acostumbrado, generalmente escribo el contenido de los mismos. Pero en este caso les deseo presentar una revista que me pareció muy interesante para ayudar a difundir, la misma se llama "The Original Hacker", fue creada por Eugenia Bahit, y trae una serie de contenido muy interesante, paso a resumir un poco de que consta esta primera edición.

Python: habla sobre una utilidad muy interesante que trae el core de Python, para poder crear y manejar de forma muy sencilla los argumentos que podemos utilizar en nuestros programas ya sean Python o script de bash.

Patrones de diseño: en este caso habla sobre el patrón Adapter, donde muestra ejemplo reales de como y porque utilizarlo, mostrándolo con código Python y PHP.

Manejo de paquetes en distribución Linux: En este caso nos muestra como manejar nuestro propios script de instalación para paquetes Debian (comentario: muy bueno!!! :D )

Formularios Web y tablas HTML: nos muestra como crearlos de manera sencilla utilizando el framework Europio (es un framework creado por la misma autora, libre, y aunque no tengo conocimientos de PHP, parece funcionar muy bien)

Y por ultimo, uno de los temas que más me gustan, que es la seguridad informática, en este caso, trata la emulación de tokens temporales como mecanismo de verificación de usuarios. Realmente creo que el contenido no tiene desperdicio.



Este es un resumen, del motivo de la publicación de la misma, por parte de la autora Eugenia Bahit:


==============================
============

The Original Hacker es una nueva revista digital, de distribución
libre y gratuita, enfocada al Software Libre, al Hacking y a la
Programación. El nombre surge en homenaje a la definición original del
término "Hacker" dada por Richard Stallman en los años '70.-

La idea era lanzarla en paralelo a Hackers & Developers Magazine,
colocando todos los esfuerzos en que The Original Hacker se
convirtiese en un complemento para H&D (ya que sería mucho más pequeña
que ésta) y que, entre ambas revistas, se dieran difusión mutua.
Lamentablemente, la idea ni siquiera llegó a plantearse, que a menos
de 36 hs de anunciar mi salida de H&D, se desintegró el equipo por
completo.-

A fin de no dejar morir el esfuerzo de todos los que habíamos
trabajado en Hackers & Developers Magazine durante un año y al no
existiendo nadie dispuesto a continuar sosteniendo el proyecto, decidí
transformar a The Original Hacker en la continuación de Hackers &
Developers.

Esta nueva etapa -una especie de "segunda temporada"- de
publicaciones, plantea artículos orientados exclusivamente a
profesionales de nivel medio en adelante, lo que sumado a una temática
fija, la hace bastante diferente a Hackers & Developers. Los temas
propuestos en The Original Hacker son:
- Ingeniería Inversa (con enfoque en la Ingeniería Inversa de Código
aplicada al desarrollo de Software y análisis de vulnerabilidades)
- Ingeniería tradicional de Software
- Seguridad Informática
- Shell Scripting orientado a SysAdmins, auditores de seguridad y afines
- y laboratorio con Europio Engine

Si bien tanto la temática como el público objetivo de The Original
Hacker se modifica sutilmente con respecto al de Hackers & Developers
Magazine, se continúa conservando el espíritu de libertad en
referencia a la elección de tecnologías tratadas en la revista y de
ética profesional y responsabilidad social, con respecto al tipo de
información que será publicada.

El lanzamiento oficial será el próximo 5 de noviembre de 2013 y la
revista será publicada periódicamente, el primer martes de cada mes en www.originalhacker.org

Entre otras cosas, la Web contará con una hemeroteca donde se podrán
descargar todos los ejemplares de la revista y de la primera temporada
de Hackers & Developers Magazine.

================================

Sitio Oficial: http://originalhacker.org/

Descargar


Espero que les haya gustado el post y sobre todo, la revista por supuesto, para resumir y como comente anteriormente, la misma trae temas muy útiles e interesantes para el que no los conocía. Creo que puede ser una buena forma, para aquellos que tienen ya conocimientos en programación, el aprender nuevas técnicas de desarrollos y nuevas herramientas, como sus utilidades. Para finalizar y sin tener menor importancia, lo bueno del contenido de la misma es su licencia libre, como el de las herramientas que nos brinda.

Saludos a todos, Gabriel