Agilistas: BASTA de tomarle la leche al gato

Hoy comencé a tomar un curso sobre ingeniería de software y una vez más me encontré con Agile vs. Waterfall. Basta por favor, como dice El Diego esto es como tomarle la leche al gato o robarle la limosna al ciego. Ojo, hacer la comparacion no está mal, lo que me parece mal es que se pretenda explicar agile comparandolo contra waterfall. Y le pegan a waterfall, una y otra vez y otra vez. ¿Porque no hacer una comparación de Agile vs Métodos orientados al plan? ¿Será que la gente aún no lo tiene claro? No sé, no entiendo, pero a esta altura escuchar gente hablando mal de waterfall me empieza a sonar molesto.

Hago un pedido a los agilista: por favor, cuando quieran presentar agile busquen algún otro mecanismo que no sea pegarle a waterfall.

Herramientas de oficina en la nube

Un de los utilitarios que aún no logré encontrar a gusto en Ubuntu es un editor de diagramas. He probado varios (Dia incluido) pero por una u otra cosa, ninguno me vino bien. Por eso celebré cuando encontré Gliffy, una aplicación web para hacer diagramas. Simplemente excelente, soporta casi todos los mismos diagramas que Visio (organigrama, red, uml, flujos, etc.).

Al igual que Prezzi, es una aplicación Flash (por si no lo conocen, Prezi es una herramienta para realizar presentaciones, funcionalmente es un competidor/reemplazo de PowePoint, pero tiene un enfoque diferente, muy recomendado).

Un detalle no menor de Gliffy es que no es gratuito, ofrece un trail gratuito por 30 dias (que es lo que estoy usando actualmente) y luego tiene un costo de alrededor de 5 dólares mensuales por cuenta.

Uruguay 2012

Con este título, esto bien podría tratarse de un evento, pero no. No es un evento sino simplemente el destino de mis vacaciones. No es que pretenda contar mis travesias vacacionales, sino que quiero compartir un fenómeno socio-cultural que me ha deslumbrado: El carnaval uruguayo. El carnaval uruguayo si bien guarda ciertas similitudes con el carnaval de argentina, la realidad es que tiene una carga social mucho más importante.

El carnaval uruguayo se desarrolla principalmente en los denominados tablados, que no son más que escenarios populares (clubes, parques, anfiteatros, etc.) donde noche tras noche se presentan las agrupaciones. Cada noche, cada tablado recibe entre 4 y 6 agrupaciones cada una de las cuales realiza una presentación de aproximadamente 40 minutos. Al mismo tiempo cada agrupación recorre entre 2 y 4 tablados por noche. Cada temporada, cada agrupación prepara un show que va presentando a lo largo de todo el carnaval en fragmentos de 40 minutos (aprox), de manera que no todos los shows son iguales.

Hay un tablado particular llamado Teatro de Verano, en cual las agrupaciones compiten ante un jurado organizados en distintas categorias.

Existen 5 categorias de agrupaciones: negros y lúbolos, murgas, parodistas, humoristas y revistas. No voy a entrar en la descripción de cada una (para ello está wikipedia), sino que voy a dar mi opinion. Muy, muy lejos, lo más interesante son las murgas. Una murga es un agrupación de entre 14 y 17 personas que conforman un grupo vocal acompañado por un bombo, un redoblante y platillos. Entonan composiciones que tratan sobre los hechos socialmente relevantes del último año y no se privan de dar sus opiniones. El contenido social/político en las composiciones de la murga es lo que marca la mayor diferencia entre el carnaval uruguayo y el argentino.

Entre las murgas más conocidas podemos mencionar Agarrate Catalina, Falta y Resto y Curtidores de Hongos.

Otro elemento destacado en el carnaval uruguayo son las Llamadas. Las llamadas son un desfile de agrupaciones similares a lo que conocemos como comparsas. Cada agrupación cuenta con un conjunto de personas que van bailando y una cuerda de tambores. Si bien esto suena muy similar a las comparsas argentinas, la principal diferencia radica en el foco de atracción: mientras que en las comparsas argentinas el foco muchas veces pasa por las bailarinas y los disfraces, en las llamadas el punto más vistoso pasa por la cuerda de tambores.

A mi humilde parecer el carnaval uruguayo no es solo un espectaculo muy vistoso sino también un fenómeno social muy interesante el cual recomiendo presenciar en algún momento.

Ubuntu update

Técnicamente no es updated, sino que simplemente decidí reemplazar mi ubuntu de 64 bits por uno de 32 bits debido a que no estaba contento con el rendimiento de mi máquina. Entonces me bajé el ISO correspondiente a 11.04, lo «quemé» en un pendrive y pisé mi antigua instalación. Luego de haber completado todo el setup, noto una leve mejora en el desempeño de mi máquina, pero nada demasiado relevante.

Les paso a contar ahora las yerbas complementarias que instalé una vez finalizada la instalación del sistema base.

Primero actualicé los repositorios utilizados por apt-get

sudo apt-get update

Lo primero a instalar es Gnome-Do una aplicación que permite lanzar la ejecución de un programa tipeando su nombre en un ventana de dialogo.

sudo apt-get install gnome-do

Continuando con los fundamentales, el siguientes paso fue instalar una extension del  explorador Nautilus para tener un menú contextual para abrir una teminal.

sudo apt-get install nautilus-open-terminal

A mi me gustan la fuentes de Microsoft, entonces:

sudo apt-get install msttcorefonts

Un utilitario infaltable es el Gimp:

sudo apt-get install gimp 

El siguiente paso es instalar Chrome, para lo cual seguí el procedimiento sugerido por Google.

Momento de instalar algunos utilitarios que funcionan como add-ons de Firefox: FireBug y FireFTP.

Llega la hora de las herramientas de desarrollo. Comenzado por Java aparece la diyuntiva de si instalar la version OpenJDK o la de Oracle. En teoría ambas siguen la misma especificación, pero la realidad es que hay reportadas menores diferencias. La buena noticia es que ambas versiones pueden convivir. Por una cuestión de simplicidad instalé OpenJDK que se instala fácilmente via apt-get

sudo apt-get install openjdk-6-jdk

Luego bajé un Eclipse classic de la página de Eclipse.

El siguiente items es el entorno Ruby, para cuya instalación me baso en el post que escribí hace un par de semanas.

Para Pharo, bajé el Zip correspondiente con la última versión de la máquina virtual y restauré mi imagen favorita desde mi pendrive.

Bien, estoy es todo para comenzar a trabajar.

Artefactos deprecados

Estaba en casa  haciendo un poco de limpieza y encontré ciertos artefactos deprecados en la actualidad, pero de uso muy común años atrás.

Lo primero que encontré fueron un par de cajas de diskettes de 5 y un cuarto, con software de distinta índole, en su gran mayoria utilitarios de DOS. Los mismos los usaba en mi primera computadora: una PC 286 de 28 Mhz con 1 mega de memoria y MS-DOS 5. No estoy seguro, pero calculo que seria año 1990, pues recuerdo pasar tardes enteras jugando a un juego de futbol llamado Italia 90. Otros clásicos de esa época eran: el Carmen San Diego, el Street Road, el Double Dragon, un utilitario llamado Print Master y el clásico Norton Commander.

Lo siguiente en sacar del placard fueron 3 cajas de diskettes de 3 y medio. Al abrirlas me encuentré con los 30 diskettes de instalación de Windows 95. ¡30 diskettes, que animalada!. Resulta que mi mamá había comprado una notebook Toshiba Satellite 100, un Pentium de 75 Mhz, que aún funciona y está guardada en algún cajón de la casa de mi mamá. Dicha máquina ya venia con el sistema operativo instalado pero traia un programa para hacer el resguardo del sistema y también las 30 etiquetas para los correspondientes discos.

Finalmente me encontré con la tapa de la calculadora científica que utilicé durante los primeros años de mi carrera (1998-2002 apróximadamente). Lo curioso es que solo estaba la tapa, de la calculadora, ni rastro. Pero ojo, que esta tapa en particular tiene un valor adicional, pues en su interior tiene anotado prolijamente un conjunto de fórmulas extremadamente útiles para el estudiante de ciencias.

Jenkins vía GTalk

Con mi llegada al mundo Ruby comencé a utilizar Jenkins como servidor de integración contínua y cuando empecé a investigar los plugins me copé. Los últimos dos que agregué fueron el HTML Publisher y el Jabber Notifier.

El HTML Publisher permite visualizar en la interface de Jenkins reportes html que se generen como parte del proceso de build; en mi caso lo uso para visualizar el reporte generado por SimpleCov. La configuracion es trivial, solo hay que indicar la ubicación y nombre del archivo del reporte.

El Jabber notifier permite enviar notificaciones vía  GTalk. Una vez instalado el plugin (que se instala con 2 clicks al igual que casi todos los plugins Jenkins) la configuración es bastante simple. En primer lugar vamos a necesitar una cuenta de gmail para que sea utilizada por Jenkins, en mi caso tengo una cuenta de gmail generada especificamente para este propósito.  Entonces en la configuración general de Jenkins (Manage Jenkins > System Configuration) en la sección Jabber Notification ponemos las siguientes settings:

  • Jabber ID: <la cuenta de gmail que queremos que Jenkings use para enviar las notificaciones> (ojo, esto no es la cuenta a la que Jenkins va a enviar las notificaciones, sino la cuenta con la que Jenkins se va logguear en GTalk)
  • Password, el password correspondiente a la cuenta de Gmail antes mencionada
  • Server: talk.google.com
  • Expose presence: yes
  • Acceptance mode for subscription requests: accept_all
  • Bot command prefix: !

Y el resto de los campos podemos dejarlos en blanco. Luego en la configuración particular de cada Job, en la sección Post-build actions, habilitamos  Jabber Notification y en el campo targets indicamos las cuentas de Gtalk a la que se debe notificar.

Les dejo un screenshot de las notificaciones que envia el Jenkins, noten lo gracioso del mensaje de estado.

Instalación de Ruby (la posta para mi)

En los últimos meses instalé Ruby en al menos 4 máquinas distintas (mi máquina personal, mi desktop del trabajo, una máquina virtual y mi build server). En todos los casos intenté seguir el mismo procedimiento, pero en todos me encontré con distintos issues, estimo que debido a que los ambientes eran levemente distintos (pero todos eran Ubuntu).

Cuando hablo de instalación de Ruby, no estoy hablando de la instalación base de ruby para hacer un «Hola  mundo», sino una instalación como para crear una aplicación «de verdad» (básicamente aplicación web, con conexión a internet, manejo de xml, pruebas y build automatizado).

Habiendo seteado el contexto paso a describir los pasos comunes que logré identificar en todas las instalación que realicé y que voy a seguir la próxima vez que tenga que preparar un ambiente.

Vamos a comenzar por instalar Ruby usando apt-get, no importa si luego queremos utilizar otra versión, yo me inclino por comenzar instalando ruby con apt-get pues eso se encargará de hacer varios seteos. Entonces abrimos una terminal y ejecutamos

sudo apt-get install ruby

Si no tenemos instalado Git aún, es un buen momento para instalarlo.

sudo apt-get install git

Luego vamos a instalar Ruby Version Manager (rvm). Esta herramienta nos va permitir instalar y administrar distintas versiones de Ruby en una misma máquina. Pero para instalar RVM primero tendremos que instalar git y curl, entonces:

sudo apt-get install curl
bash -s stable < <(curl -s https://raw.github.com/wayneeseguin/rvm/master/binscripts/rvm-installer )
echo '[[ -s "$HOME/.rvm/scripts/rvm" ]] && . "$HOME/.rvm/scripts/rvm" # Load RVM function' >> ~/.bashrc

Cuando finalice la instalación de estos componentes cerramos la terminal.

Ahora instalaremos ruby 1.9.2 usando RVM, para ello abrimos una nueva terminal y ejecutamos

rvm install 1.9.2

El siguiente paso es installar RubyGem, un administrador de paquetes (que en ruby se llaman gemas). La instalación de esta herramienta consisten en descargar el paquete desde http://rubygems.org/pages/download , descomprimirlo y ejecutar setup.rb (ruby setup.rb). Con esto ya estamos en condiciones de comenzar a installar gemas, pero resulta que algunas gemas en su proceso de instalación incluyen un proceso de compilación de código C, el cual puede requerir de la existencia de ciertas librerías nativas en nuestro ambiente. Por suerte las mismas pueden instalarse fácilmente utilizando apt-get.

sudo apt-get install libmysqlclient-dev libpq-dev libsqlite3-dev zlib1g-dev libreadline5-dev libssl-dev libxml2-dev libopenssl-ruby libxslt1-dev

Ahora  si, podemos proceder a la instalación de dos gemas fundamentales: rake (ruby make) y bundler (un administrador de dependencias en un punto similar a Maven).

gem install rake
gem install bundler

Con esto estamos listos para comenzar, cuando creemos nuestras aplicaciones tendremos un archivo llamado Gemfile en el cual especificaremos las dependencias de nuestra aplicación (las gemas) y con solo ejecutar bundle install, bundler se encargará de instalar las gemas especificadas.

Espero que esto les resulte útil.

Continué con Ruby y me copé

Luego de mi comienzo en el mundo Ruby, seguí avanzando: agregué tests (utilizando rspec), medí la cobertura (con simplecov) y automaticé el build contínuo (con rake y jenkins). Ahora que tengo todo mi código cubierto por pruebas voy aplicar algunos refactorings pues no estoy muy conforme con los nombres de algunos métodos y al mismo tiempo quiero agregar algunas funcionalidades nuevas. Lo que aún me falta agregar es algo que verifique el cumplimiento de estándares de codificación.

Si bien aún soy un principiante en el mundo Ruby, puedo afirmar que hacer el setup de todo lo mencionado arriba en un proyecto Ruby, me ha resultado mucho más simple que hacerlo para un proyecto C#, a pesar de la experiencia mucho más extensa que tengo con este último.

¿Y si tu sueldo dependiera de la cobertura de tu código?

Definitivamente algunos meses habría pasado hambre  y  creo que algunos otros no habrían cobrado ni un solo peso, ja!

Más allá de lo chistoso (o lo triste) del título, este post es una continuación  de otro que escribí hace un par de dias sobre esta misma temática. En dicho post compartí algo de teoría junto con algunos links interesantes (el de artículo de Marrick es excelente) y en los cuales he encontrado justificación para algunas de las ideas que compartiré a continuación. Durante las últimas semanas he estado dedicando la mitad de mi tiempo en entrenar gente y la otra mitad al desarrollo de una aplicación y en ambos casos he puesto bastante foco en el tema de la cobertura de código lo cual me ha llevado a una reflexión profunda sobre el tema.

Si desarrollamos nuestra aplicación siguiendo un enfoque TDD extremo, siempre mantendremos un alto grado de cobertura, pues solo agregaremos código cuando haya una prueba que lo ejercite.

Si procuramos seguir las buenas prácticas de diseño la relación entre nuestros componentes será por medio de interfaces, lo cual nos permitirá utilizar mocking y asi superar la infantil excusa «No lo puedo testear porque tiene dependencias».

Si nuestros métodos son cohesivos y hacen usa sola cosa, entonces será más simple testearlos.

Si hechamos mano del polimorfirmo, seguramente podamos evitar algunos «if» en nuestro código lo cual también ayudará con la cobertura.

Para cerrar este post, les comparto una situación que viví hace unos dias. Resulta que una de las personas que estuve capacitando durante la semana pasada hizo una demo de la aplicación que desarrolló como parte de la capacitación. La demo venia bien y en un momento le pedimos que mostrara una funcionalidad particular que no habia sido mostrada. Resulta que cuando la va a mostrar, la aplicación ¡pincha!, ja!  a lo que le pregunto: ¿y los tests? adivinen….no había tests para esa funcionalidad. Y cuando pregunto por el porcentaje de cobertura de la aplicación, resulta que no superaba el 40%. ¡Que mejor forma de ilustrar la importancia de estas cuestiones! Espero que este colega haya aprendido la lección.

Por último quiero agradecer a David Frassoni quien la semana pasada me dió la idea de escribir este post.

El siguiente post de esta serie lo dedicaré a analizar las implicancias/consecuencias de tener una alta cobertura y de definir un shipping criteria en base al mismo.

Continuará…

Code Coverage

Durante las últimas semanas he estado dedicando la mitad de mi tiempo en entrenar gente y la otra mitad al desarrollo de una aplicación y en ambos casos he puesto bastante foco en la cobertura de código. Esto me ha motivado a compartir algunas ideas sobre este tema y para setear el contexto y las expectativas, voy comenzar este post compartiendo algunos conceptos básicos y luego en otro post voy a volcar algunas ideas/experiencias personales.

¿Qué es la cobertura de código?

La cobertura código es la cantidad de código (medida porcentualmente) que está siento cubierto por las pruebas. O sea, ejecuto las pruebas de mi aplicación y si hay alguna línea de mi código que nunca fue ejecutada en el contexto de las pruebas, entonces dicha línea no está cubierta. Si mi código consta te 100 líneas y solo 50 líneas están siendo ejecutadas al correr las pruebas, entonces mi cobertura es del 50%. La pregunta que viene a continuación es:

¿Qué beneficio tiene medir la cobertura? y más específicamente ¿que beneficios tiene tener una alta cobertura?.

Una respuesta genérica podría ser que aumenta la calidad de mi aplicación. Siendo más concreto podría decir que si tengo una alta cobertura, significa que gran parte me mi código está siendo probado y por consiguiente podria tener cierta certeza sobre el correcto funcionamiento de mi aplicación. Al mismo tiempo medir la cobertura podria ayudarme a detectar código innecesario en mi aplicación, ya que no se ejecuta.

La pregunta que surge a continuación es:

¿Qué porcentaje de cobertura es suficiente?

La respuesta no es única, existen distintos criterios y pueden resultar bastante polémicos por eso voy a tratarlos en otro post. Pero por ahora solo diré que para SimpleCov, lo idea es de al menos 90% y en Southworks soliamos perseguir el 80%.

¿Una cobertura del 100% asegura que mi código no tiene bugs?

De ninguna manera, una cobertura del 100% solo nos dice que todo nuestro código está siendo cubierto por pruebas, pero puede que las pruebas no esten contemplando algunas situaciones, o sea, me falta pruebas.

¿Qué necesito para poder medir la cobertura?

En primer lugar  es necesario escribir pruebas y en segundo lugar contar con alguna herramienta que permita medir la cobertura.En la actualidad los lenguajes más populares cuentan con herramientas para medir la cobertura. Si trabajamos con C# y escribimos nuestras pruebas con MSTest, entonces el Visual Studio nos ofrece la posibilidad de habilitar la medición de cobertura de código. Si en cambio trabajamos con Ruby, podríamos utilizar RSpec para escribir nuestras pruebas y SimpleCov para medir la cobertura.

Esto es todo por ahora, les algunos links interesantes sobre el tema:

En el siguiente post voy hacer algunos comentarios sobre estos artículos.