Developing Frogtek

El blog del Departamento de Tecnología

Categoría: herramientas (página 1 de 3)

La comunicación y las nuevas herramientas: Slack

Siguiendo con el tema de la comunicación que ha iniciado Miky, me gustaría ahondar un poquito más en el tema.

El día 1 de abril, en Zaragoza, acudí al siguiente meetup donde Francho nos explicó cómo en su empresa, Spines, usan Slack y sus distintas integraciones. Siendo el centro de estas integraciones Hubot, un bot que permite realizar una serie de automatismos e integrar servicios y acciones fácilmente con Slack.

Como buen friki que soy tengo muchas ganas de montarme mi propio Hubot y ponerlo en nuestro Slack, pero eso no fue lo que más me llamó la atención de la charla. Lo que más me tocó fue el que ellos llevarán casi toda la comunicación a través de Slack. El email lo usaban lo mínimo. Según nos contó Francho en su cuenta de correo de la empresa sólo tenía 5 mails en los dos años y pico de empresa que llevan. Para poder llegar a esto, nos comentó que la clave residía en la separación correcta de las conversaciones en distintos canales, permitiendo así la selección de las conversaciones y facilitando la búsqueda y lectura de las mismas.

Como ya comentó Miky nosotros llevamos menos tiempo con Slack y nos ha reportado ya una serie de beneficios increíbles. No tengo claro que el objetivo deba ser abandonar el email del todo, pero sí que veo que para ciertos tipos de comunicación deberíamos tender más a Slack, sobre todo en torno a emails automáticos y alertas. Además creo que el tema de los canales por conversación tiene mucho sentido. Ahora mismo sufrimos, entiendo, uno de los primeros anti-patrones de uso de Slack, que es mezclar y tener muchas conversaciones en un mismo canal. No es que tengamos un único canal, ni mucho menos, pero igual deberíamos plantearnos dividir alguno más y acostumbrarnos a hacer un buen uso de los canales.

Al fin y al cabo es lo mismo que ocurre con el email. Con un buen uso de la herramienta se puede conseguir mejorar mucho la comunicación, sobre todo su calidad y facilidad de lectura. Aplicar una herramienta nueva lleva su tiempo y se necesitan distintas iteraciones hasta que se consigue dar en el clavo. Tenemos que trabajar en ello, así que ya tengo tema para la siguiente retrospectiva.

Comunicación: ajustando una máquina compleja (Work In Progress)

Comunicación: ajustando una máquina compleja (Work In Progress)

En Frogtek trabajamos personas desde diferentes sitios de la geografía mundial. Principalmente trabajamos desde varias ciudades de tres países: México, Colombia y España. Pero también tenemos que trabajar con gente en los EEUU y otros países. Y este aspecto en una empresa, sin duda alguna, es todo un reto.

Si ahora volvemos la vista atrás se podían ver varias máquinas (una por país) trabajando cada una con su entorno, dando lo mejor de ellas mismas, y de vez en cuando interactuando con las demás. Diferentes procedimientos, diferentes expectativas y prioridades, diferentes zonas horarias, diferentes culturas, … al final demasiadas diferencias que hacían que las interacciones entre las diferentes máquinas estuvieran lejos del óptimo.

Desde hace unos meses se ha realizado un esfuerzo notable y global en toda la empresa por homogeneizar la comunicación y los procesos. Un esfuerzo donde cada una de las máquinas debe entender la forma de trabajar del resto, buscando empatía en los diversos problemas que aparecen en otros engranajes, mejorando de forma proactiva todo lo que se puede.

Todavía hace falta mucho “3 en 1”, pero esas máquinas independientes que había antaño se han convertido en varios módulos que se relacionan de forma constante los unos con los otros. Parece que los primeros pasos se han dado y ahora la máquina evoluciona de forma autónoma. Las relaciones se estrechan y se agilizan, se minimizan las esperas. ¿Qué ha cambiado en este tiempo?
Seguir leyendo

La regla del boy Scout

Desde mi último cambio de trabajo le he estado dando vueltas a un tema que me parece interesante.

Por un lado en el traspaso de conocimiento que hice antes de irme de Zentyal, la persona que se incorporaba llegó con energía, cuestionándose las cosas y mejorando en general todos los sistemas que yo le estaba traspasando. Había cosas que él proponía que me costaba aceptar. Seguramente porque no quería reconocer que me había acomodado, ya no buscaba las mejoras con el mismo ímpetu y ganas; y había dejado que ciertas áreas se estancaran bastante.

Al entrar de nuevo en Frogtek sí que fui yo el que se puso a buscar dónde aplicar todo lo aprendido desde mi última vez por aquí, planteando mejoras y buscando sitios donde aplicar mis conocimientos para el provecho del equipo. Ahora voy con mucha energía y ganas, pero me da miedo que dentro de un tiempo vuelva a acomodarme otra vez y me cueste buscar mejoras y realizarlas.

Creo que el problema tiene mucho que ver con la teoría de las ventanas rotas. Al principio, al llegar, quiero mejorarlo todo porque creo que el edificio esta nuevecito, para mí obviamente lo está. Pero conforme pasa el tiempo y voy conociendo más los entresijos de la empresa, el equipo, el código… se me van rompiendo las ventanas y me va dando más pereza intentar arreglarlas. Porque me parece el estado normal, total una ventana más o menos qué más da,  ¿no? ¿ Qué importa un archivo sin usar en el repositorio, una librería desactualizada, un proceso mejorable o unos tests de más o menos?

¡¡Mucho!! Por eso creo que es muy importante La regla del boy Scout, pero no sólo aplicada al código, sino a todo. Cada vez que toquemos un archivo del repo, cambiemos una configuración de Jenkins o simplemente asistamos a una reunión del proceso. Hay que estar atentos para buscar esos pequeños cambios o mejoras que nos van a permitir poco a poco llevar nuestro trabajo, y el del todo el equipo, a otro nivel.

Hay que tener paciencia y no desesperar, no sólo los grandes refactors pueden ayudarte a saber vivir con tu deuda técnica, pequeño paso a pequeño paso se puede llegar muy lejos. A ver si soy capaz de tener paciencia y aplicarme esta última frase.

Google App Engine: Lanzar un MapReduce desde un Cron (Segunda Parte)

Hace más de un año, Alberto nos explicaba cómo lanzar un MapReduce desde un Cron en Google App Engine. Desde entonces ha llovido mucho. Google App Engine ha evolucionado y madurado, trayéndonos mejor documentación y una comunidad más activa.

Gracias a ello he podido encontrar una solución más sencilla que la que os ofrecímos en nuestro último post al respecto. Digamos que queda mucho más sencillo 😛

from mapreduce import control
 
mapreduce_id = control.start_map(
"My Mapper",
"main.my_mapper",
"mapreduce.input_readers.DatastoreInputReader",
{"entity_kind": "models.MyEntity"},
shard_count=10)

Cuidado con el shard_count. Aseguraos que corresponde con el que tenéis configurado en vuestra aplicación.

 

Afinando GIT

Después de varios meses trabajando en la migración a GIT, finalmente podemos decir que todo ha salido a pedir de Milhouse. Además nos ha servido para darnos cuenta de que vamos a tener que acostumbrarnos a que el sistema de control de versiones sea una parte fundamental de nuestra metodología de trabajo. Principalmente por el gráfico que aparece a continuación. Está extraído de este gran artículo sobre control de ramas con GIT. De él obtuvimos la inspiración para realizar nuestro sistema de branching, pero no es de esto de lo que queremos hablar…

Más bien queremos contar algunos ajustes que hicimos a la configuración de git para que nos sea más usable.

  1. Crear unos cuantos útiles “alias”:
  2. Lo primero es editar nuestro archivo .gitconfig, añadiendo algunas versiones cortas de los comandos más usados.

    [alias]
            co = checkout
            ci = commit
            st = status
            br = branch
            brancha = branch -a

    Aquí va uno muy útil: mostrar el listado de commits en una línea cada uno y mostrando los autores al principio (todo ello a color):

    hist = log --graph --decorate --pretty=format:'%C(bold blue)%Creset
    %Cred%h%Creset -%C(yellow)%d%Creset %s %Cgreen(%cr)'
    --abbrev-commit --date=relative

    Los dos siguientes son muy útiles para gestionar los archivos y carpetas marcados como unchanged:

    unchange = update-index --assume-unchanged
    unchanged = !git ls-files -v | grep ^[a-z]

    El primero nos permite marcar un archivo como “assume unchanged”, en caso de que no queramos que tenga control de versiones. El segundo nos muestra qué archivos de nuestro repositorio están marcados de esta forma.

    Crear una nueva branch asociada a una nueva historia de usuario:

    us = "!f() { git checkout -b US$1; }; f"

    Este comando funciona de la siguiente manera. Si tecleamos US 13, nos creará una nueva branch (desde la que estemos en ese momento) con el nombre US13. Muy útil.

    Y para acabar, activar el color para todos los comandos de GIT:

    [color]
            ui = true
  3. Pasarnos a bash y crear más “alias“:
  4. alias go='git checkout'
    alias gp='git pull'
    alias gs='git status'

    Cambié mi terminal para que usara bash como intérprete, ya que me permitía funciones adicionales como la del punto 3. Después añadí unos cuantos alias entrando en el home y editando el archivo .bash_profile

    Hay gente que prefiere utilizar el comando completo, es cuestión de gustos. He añadido git pull y git status porque son algunos de los comandos que más uso en consola.

  5. Mostrar la rama actual en el shell de bash. Esto ya lo vimos en capítulos anteriores.

Y esto es todo. Recordad que lo principal es que cada uno configure sus instrumentos a su voluntad. Al fin y al cabo, se trata de estar a gusto con las herramientas que utilizas.

Visualizar el servidor de integración continua

Monitor de monitorizaciónOs presento la última “frikada” que hemos añadido a nuestra colección de gadgets de oficina.

Con el viejo servidor, actualmente en desuso, una pantalla vieja y el plugin de Jenkins  eXtreme Feedback Panel Plugin. Hemos montado un visualizador del estado de nuestro servidor de integración continua (Jenkins).

El objetivo esta claro. Conseguir estar enterados en todo momento de la salud de nuestras construcciones. Ya no vale eso de “no vi el email”.

Además informa del culpable de la rotura si la hay. Y muestra el número de tests añadidos en la última construcción, entre otras virguerías.

 

 

 

Pomodoros de verdad

La última semana tuvimos el placer de acoger en las oficinas de Frogtek al freelance y experto en craftmanship Enrique Comba (@ecomba), el cual trabajó codo con codo con nosotros para ayudarnos a mejorar nuestro proceso.

Siendo un experto en la materia como es él, aprovechamos para preguntarle cómo mejorar nuestros pomodoros. La técnica del pomodoro es un método de timeboxing (administración del tiempo) para realizar tareas en periodos alternos de trabajo exhaustivo y pausas. Nosotros ya habíamos integrado esta técnica a nuestro trabajo habitual, y esto era lo que sabíamos:

  • Cada pomodoro consiste en un periodo de trabajo continuo de 25 minutos.
  • Durante ese tiempo, hay que trabajar concentrándose en la tareaevitando cualquier distracción (correo, twitter, etc.). Algunas distracciones, sin embargo, son inevitables, como otros compañeros preguntando una duda, una llamada al teléfono, etc.
  • Un pomodoro es indivisible (no existe medio pomodoro). Lo utilizamos como unidad atómica de trabajo.
  • Después de cada pomodoro, hay que tomar una pausa breve de 5 minutos.
  • Después de un cierto número de pomodoros (entre 3 y 5 en nuestro caso) hay que tomar un descanso largo, de entre 15 y 25 minutos.
  • Al principio de cada jornada de trabajo, hay que planificar los pomodoros y descansos que se van a realizar.
  • Además hay que estimar cuánto tiempo (medido en pomodoros) va a costar realizar una tarea determinada.

Sin embargo, Enrique nos dio algunos consejos sobre las pausas, que no estabamos aplicando:

  • Es muy importante levantarse del asiento e incluse hacer ejercicios para evitar contracturas.
  • Debe intentar dejarse la mente en blanco. Esto es debido a que nuestro cerebro almacena la información y crea conexiones o momentos de inactividad, como durante el sueño.
  • No vale mirar el correo o twitter. Si es necesario utilizarlo, mejor tomar un pomodoro de “comunicación” de 25 minutos para realizar este tipo de tareas.

Sobre las distracciones:

  • Cualquier distracción (tanto interna como externa) debe anotarse en un papel, indicando su procedencia.
  • Al acabar la jornada, habrá que revisar la lista de distracciones y comprobar si pueden reducirse de alguna manera. En caso contrario, intentar agruparlas dentro de un mismo pomodoro.

Para más información, recomiendo leer este PDF del propio creador de la Técnica Pomodoro, Francesco Cirillo.

Prototipado con Google Spreadsheets y Fusion Tables

Confome avanzan nuestros proyectos, va aumentando el volumen y calidad de la información subida por los usuarios desde sus dispositivos Android. Toda esta información se va agregando en la nube y poquito a poco vamos entrando en una nueva etapa en la que el data mining va cobrando más importancia. De momento, tenemos claros ciertos tipos de informes y gráficas imprescindibles para nuestro negocio, pero las posibilidades de jugar con los datos son enormes y, por eso, necesitábamos un modelo que nos permitiera diseñar de forma ágil prototipos funcionales para ser mostrados y estudiados por nuestro equipo, clientes y colaboradores.

Es necesario explicar que, aunque ya tenemos varios agregados e informes mostrados en la propia nube, también  descargamos y desnormalizamos los datos sobre una MySQLinstalada en un servidor local, ya que, las posibilidades de “retorcer” los datos en una base de datos relacional son mucho mayores que en un sistema como Big Table . Por tanto, llegados a este punto, contamos con un servidor local, una base de datos MySQL y un equipo de ingenieros preparados para torturar a los datos con las más despiadadas queries.

Una vez obtenida la información que pensamos que interesa a nuestros usuarios, las posibilidades de representarla son muchas, existiendo innumerables librerías Javascript para mostrar tablas y gráficos, (o incluso empresas ofreciendo herramientas SaaS muy potentes).  El problema es que todas ellas requieren preparar los datos con un formato concreto y cierto trabajo de programación y maquetación para integrarlas en una web.  En nuestro caso, pensamos que es pronto para emplear tiempo en ese tipo de tareas, puesto que no estamos seguros de qué tipo de representaciones van a ser valiosas y cuáles no. Aquí es donde entra en juego una gran idea de nuestro CEO: tanto Google Spreadsheets como Fusion Tables permiten importar datos desde CSV y la generación de listados, figuras y gráficas es potente y muy sencilla.

Las ventajas son muchas:

  • Ambas herramientas permiten importar los datos desde CSV. Y cualquier cliente SQL permite exportar los resultados de una query en dicho formato, por lo que la tarea de formato de datos estaría resuelta.
  • Ambas permiten generar automáticamente un script para incrustar los datos en cualquier web.
  • Los datos generados en el prototipo, aunque estáticos, son reales. Y su actualización (manualmente o usando las APIs proporcionadas) sería muy sencilla. Tan fácil como ejecutar de nuevo la consulta y exportar el CSV.

¿Qué usamos entonces para tener listo un conjunto de listados y gráficos demo con información real?

  • Google App Engine con Django: La facilidad de despliegue de una nueva aplicación en el GAE unida a la rapidez de desarrollo en Django nos permitieron montar la estructura de navegación del nuevo portal en una sola mañana (reutilizando plantillas y  diseños que ya teníamos).
  • Listados y gráficas:  Una vez obtenida la consulta sql con los datos que nos interesaban, la exportamos a CSV y la importamos en una de las dos herramientas comentadas:
  • Google Spreadsheets: una vez importado el CSV y obtenida la URL, podemos hacer uso de los múltiples google gadgets disponibles para  incrustar en nuestras webs. Por ejemplo, tablas, gráficos de líneas o de tarta.
  • Fusion Tables: una vez importado el CSV y obtenida la URL, podemos probar los distintos tipos de visualizaiones a partir del menú Visualize. Las opciones son variadas y potentes. Alguna de ellas bastante espectacular (Motion, Timeline, Story Line…).

Normalmente utilizamos Balsamiq para proptotipar y hacer pruebas de usabilidad en la fase de diseño, pero en este caso necesitábamos algo más real. Con todo lo anterior, en muy poco tiempo, logramos desplegar un prototipo operativo que permite mostrar el potencial de los datos recogidos y experimentar con distintas formas de mostrar la información. ¿Qué ventajas e inconvenientes le veis? ¿Qué alternativas usáis vosotros para esta tarea?

VirtualEnv para Google App Engine en local

Por defecto en Google App Engine , hasta hace bien poco, solo se podía usar hasta la versión 1.1 de Django. Esto generaba problemas si tenías alguna otra aplicación web que requería una versión más reciente de Django, como por ejemplo nuestra herramienta de revisión de código. Obtenías una serie de conflictos que eran una molestia para el desarrollo y uso en local del servidor, impidiendo un desarrollo fluido y una configuración estable.

La solución por la que optamos fue usar virtualenv. Con esta herramienta podríamos separar el entorno de ejecución de Google App Engine, del resto de aplicaciones instaladas, tanto en el servidor de integración continua como en los equipos de los desarrolladores.

Después de consultar varios sitios web al respecto, el proceso de configuración quedo algo así:


aptitude install python-virtualenv python-pip

Para instalar tanto el propio virtualenv como pip, una herramienta para instalar paquetes en dicho entorno.


virtualenv --no-site-packages --python=python2.5 ENV

Para configurar en ENV el entorno. –no-site-packages indica que no herede ningún package de la instalación de la cual se toma python y le indicamos que queremos la versión 2.5 pues GAE se ejecuta en con la 2.5 en los servidores de Google.

pip install -E ENV Django==1.1

Añadimos la versión de Django que utilizar con pip.

Para finalizar ya solo falta copiar la carpeta de Google App Engine dentro de ENV. Activar el entorno utilizando un par de scripts que hay en ENV/bin/ y lanzar el servidor de desarrollo.

Ahora mismo toda esta parafernalia tiene algo menos de sentido pues en la última versión del SDK del GAE han añadido la versión 1.2 de Django. Pero aún así puede ser útil para conseguir un entorno controlado y separado del resto de la máquina. Ya sea un servidor de integración continua o nuestra propia máquina de trabajo.

Robolectric: TDD en Android

Llevábamos ya desde nuestros inicios buscando herramientas que nos permitieran practicar TDD para desarrollar las clases de nuestro proyectos en Android. El problema era que las Activity (clase fundamental de las aplicaciones Android) solo podían ser testeadas a través del propio entorno Android, nunca como clase independiente. Por lo tanto, los únicos tests que habíamos realizado sobre esas clases eran tests de integración, que podían tardar del orden de 4 minutos en ejecutarse por completo, lo que nos imposibilitaba el realizar un diseño guiado por tests.

Robolectric (http://pivotal.github.com/robolectric) es una herramienta que nos va a permitir lanzar tests unitarios en Android.

Su uso nos aporta varias ventajas:

  • Ejecuta tests en Android que duran segundos y no minutos, como en el caso de un Android jUnit test.
  • Su velocidad nos permite practicar TDD al crear clases en Android.
  • Podemos usar Mockito o PowerMock en conjunción con los tests de Robolectric.
  • Nos permite utilizar clases de librerías Android, como JSONObjects o JSONArrays, que en otros entornos no podríamos usar.

Como algunas clases de Android no tienen métodos para acceder al estado o las variables que contienen, la gente de Robolectric se ha sacado de la manga los Shadows (ShadowImageView, ShadowRelativeLayout, ShadowActivity, etc.), los cuales nos van a permitir realizar pruebas como esta:

@Test
public void testImagenEsCorrecta() throws Exception {
    ImageView imagenBanner = (ImageView) activity.findViewById(R.id.banner);
    ShadowImageView shadowBanner = Robolectric.shadowOf(imagenBanner);
    assertThat(shadowBanner.resourceId, equalTo(R.drawable.img_banner_grande));
}

Cómo configurar Robolectric para Eclipse:

Estos son los pasos básicos para configurar Robolectric en Eclipse. Recomiendo seguir el quick-start de la web oficial para más detalles:

  1. Crear una nueva carpeta en la raíz de nuestro proyecto que vamos a testear, llamada test.
  2. Crear un nuevo proyecto (u obtenerlo del SVN) llamada MyProjectTest.
  3. Queremos meter el código dentro de la carpeta test antes creada, así que en MyProjectTest haremos clic en propiedades y en Build Path/Source/Link Source seleccionaremos la carpeta test.
  4. Añadir al proyecto el .jar de Android.
  5. Añadir al proyecto el .jar de Robolectric (¡con dependencias!).
  6. Añadir una nueva run configuration en Run/Run configurations, de forma que elijamos Eclipse JUnit launcher y en la pestaña Arguments seleccionaremos Other/Workspace y elegiremos la carpeta raíz del proyecto que queremos testear.

Ejemplo de uso para testear una Activity:

@RunWith(RobolectricTestRunner.class)
public class MyActivityTest {
    private Activity activity;
    private Button pressMeButton;
    private TextView results;

    @Before
    public void setUp() throws Exception {
        activity = new MyActivity();
        activity.onCreate(null);
        pressMeButton = (Button) activity.findViewById(R.id.press_me_button);
        results = (TextView) activity.findViewById(R.id.results_text_view);
    }

    @Test
    public void shouldUpdateResultsWhenButtonIsClicked() throws Exception {
        pressMeButton.performClick();
        String resultsText = results.getText().toString();
        assertEquals("Testing Android Rocks!", resultsText);
    }
}

De momento, Robolectric es un proyecto joven (surgió en noviembre de 2010). Esperamos que esta herramienta mantenga una cierta continuidad, para que podamos obtener el máximo rendimiento a las prestaciones que nos ofrece.

Por ahora estamos experimentando las posibilidades que nos otorga, todavía nos queda por descubrir como crear nuestros propios objetos Cursor dentro de este entorno. Seguiremos informando…

Antiguas entradas