The Landscape of my Dreams

3May/1219

Talento, Startups y Desarrollo

Posted by semurat

Cada cabeza es un mundo

Este post intenta ser una visión muy subjetiva, personal y puede diferir mucho de lo que tú que lo lees puedes pensar sobre este tema. Desde este primer párrafo te doy la razón, no te la voy a quitar ni la voy a discutir. Son diferentes puntos de vista y el mío es tan bueno o tan equivocado como el tuyo. Con todo esto debo hacer un disclaimer y decir que es mi opinión y lo que he vivido y seguramente en cada caso sea distinto en un porcentaje alto, o no.

Talento

Durante los últimos años hay una palabra que aparece una y otra vez cada vez que oyes a hablar a gerentes, directores o responsables de equipos: TALENTO. A veces parece que la búsqueda de talento es algo que se hace desde hace poco tiempo, como si antes nunca se buscara, o como si el talento apareciera en cualquier esquina. Realmente lo que se busca es gente con ganas de trabajar, que lo haga bien o muy bien y que esté comprometida con la empresa o proyecto en que trabaja.

Cada vez que alguien se dirige a mi buscando talento pienso en la cantidad de buenos profesionales que sacarían ese trabajo adelante pero que no entran dentro de ese grupo de personas talentosas, pero sí en el de trabajadoras. ¿Debemos dejarlas fuera del mercado laboral? Y lo que es peor, y no sé si os pasará lo mismo... yo no me considero una persona con talento, sino constante e implicada en donde trabajo. Y creo que lo hago bien, modestia aparte, y tengo capacidad de aprender y ponerme al nivel que haga falta.

¿Qué ocurre con las startups y el talento?

Es curioso como en España, y hablo de España porque es el mercado que he conocido en estos dos últimos años y tengo datos cercanos, se busca el talento. Las empresas buscan gente muy buena y salvo ciertas empresas que se nombran que pagan bien (dicen que Tuenti) el resto pagan salarios ajustados a su estado de inversión y de situación financiera.

Oir comparaciones con Estados Unidos, con Silicon Valley y demás nichos de empresas de nuevas tecnologías es una TONTERIA. En primer lugar por la situación económica de ambos países, por su PIB y por el salario medio en nuestra profesión, pero aún más importante...por la cultura empresarial. Escuché el otro día a Enrique Dubois diciendo que es bueno invertir en España, entre otras ventajas porque un desarrollador en USA cuesta $100k, mientras que en España es más barato +/- 30k € o hacerle socio tecnológico. Salvando la diferencia de salario, olvidó decir que en USA también se puede pagar algo menos y hacerle sociotecnológico. No es malo, es una forma de balancear el capital de la empresa implicando a la pieza fundamental en una empresa tecnológica. Lo que me molestó es el sentido que se sacaba de esa frase: invertir en desarrolladores en España está bien porque son baratos. Me hubiera gustado mucho más oir en su boca y con su experiencia palabras tales como: invertir en España está bien porque el nivel es comparable al de cualquier otro país, y económicamente la inversión en la contratación es menor por la economía del país.

En todo caso, compensar el salario del desarrollador haciéndole tu socio tecnológico es una solución buena, correcta y rentable, pero tiene un problema: intentas que el desarrollador adopte tu sueño empresarial, le intentas convencer de tu idea de negocio...y olvidas que a la larga es tu idea. Nunca la vivirá igual, porque los desarrolladores vivimos ilusionados por los proyectos, mientras el proyecto sea excitante y motivador dará incluso más que tú, pero cuando se vuelva rutina, el sueño dejará de estar presente en él y buscará otros retos.

Hay profesionales que dicen que si el proyecto vale la pena el dinero pasa a segundo plano, y es algo que he vivido en mis propias carnes cuando he cambiado de trabajo. Seguramente mi evolución salarial no ha sido la misma que otras personas, cuando he cambiado de trabajo ha sido por razones de motivación, de hastío o de evolución profesional y puedo decir que siempre he sido un mal negociador de mi salario y he valorado muy poco lo que yo aportaba a cambio de dinero. Bien, es verdad que pasa a segundo plano, pero todo tiene un límite. No esperes encontrar talento o lo que tú consideras talento pagando 20k €. Luego saldrán diciendo que el talento no existe en España. Existe, y está muy cerca de ti...pero esas personas con talento tienen un precio, porque normalmente trabajan en sitio donde están cómodos, son reconocidos y probablemente ganen lo que desean, porque si tienen talento pueden buscar sitios donde ganar más. No es cuestión sólo monetario, pero ayuda. Ofrece un proyecto ilusionante, un reto tecnológico y tendrás el talento llamando a tus puertas...pero compensa con un salario digno. Si no lo haces vendrán otros con proyectos iguales o más motivadores con un salario mayor y se llevarán a tu talento.

Estoy cansado de oir a emprendedores que justifican que alguien no tiene talento o que no existe. Tienes el talento que puedes pagar, ni más ni menos, trayendo talento con la suma de dos variables: reto tecnológico + dinero.

Sí, ya sé...como no tienes dinero puedes compensar ofreciendo Stock Options, participaciones de tu empresa a los empleados y eso es algo muy común en Estados Unidos y es una forma correcta de cubrir la falta de dinero para pagar buenos salarios y de implicar al equipo con el producto. Es una opción muy buena, pero a veces no es comprendida por los empleados y hay que explicarla muy bien.

Y algo que no puedes hacer tampoco es tener un doble mensaje: "la base de la idea de negocio es la solución tecnológica del producto, pero te doy un porcentaje menor o no lo reparto al 50% contigo". Me parece genial, me estás diciendo que me buscas porque soy la leche, porque es imprescindible hacer un buen producto y romper el mercado y como no hay suficiente dinero me darás un % pero luego no me das lo mismo o eres un poco mísero al repartir. Creo que así los números no salen y la famosa implicación que intentas vender se va diluyendo según pasan las rondas de financiación, por ejemplo.

Composición de la empresa

Una de las grandes cosas que he aprendido estos dos años es lo importante que es la parte de Marketing y ventas en una empresa. Los desarrolladores somos unos ególatras...sí sí, nos creemos el centro del universo, pensamos que somos los mejores y lo de los demás es una mierda. Yo soy el primero que pone a caer de un burro la web de Renfe cuando no puedo pagar mis billetes o falla los domingos por la noche. Y no esta bien que falle!!! Ojo que no estoy diciendo eso ;)  Sí, es cierto, es IMPORTANTE tener un producto bueno, fiable, robusto, escalable, etc, etc. Pero si lo conoce sólo la portera y tu madre te aseguro que no vendes nada, para eso desarrolla proyectos, súbelos a Github y que todos disfruten criticando tu código o revisandolo o aportando nuevas funcionalidades. Pero olvida lo importante: hay que monetizar tu trabajo, y si no haz proyectos para ONG's y ayuda a gente más necesitada. Si te metes en un negocio es para ganar dinero, y cuanto más mejor. Y para conseguir dinero hay que vender tu producto, y no hablo de comerciales, esos que durante años han conseguido que les veamos como aquellos que venderían a su madre para cerrar una venta con apetitosa comisión, sino de gente que son capaces de posicionar tu portal o plataforma en internet. Aquellos que estudian el mercado y toman medidas de corrección en base a los datos que Google Analytics o las herramientas que empleen les dan información. Los que son capaces de cerrar acuerdos con otros medios, blogs, plataformas buscando un WIN-WIN entre las dos partes. Y sobre todo, los que entienden el mercado en que te mueves y el producto que estas lanzando.

Sí, señores desarrolladores...no tenemos ni idea de vender por regla general, y de comunicar... a veces lo justo.

Otro punto que he visto en ciertas ofertas de trabajo, o posiciones a cubrir es la composición de empresas en base a becarios. Muy loable el incorporar gente sin experiencia pero cualificada a puestos de trabajo para que aprendan y se realicen en la empresa. Está muy bien que esos becarios terminen formando parte de tu pequeña familia y terminen con un contrato encima de la mesa para que sigan creciendo contigo. Lo que no veo bien es que por querer hacerle uno más en la empresa les impliques con la misma carga y presión que cualquier otro empleado. Los becarios están para aprender, no para hacer tu trabajo. Durante 12 años pasando por diferentes empresas he visto como se cogían becarios y desde el primer día se les ponía a trabajar y a hacer horas extras como si nada...y lo que es peor, llegar a oir a responsables decir que en cualquier momento podían explotar y marcharse, pero que daba igual, se podían encontrar más en cualquier momento. Eso es un ERROR. Un becario tiene que ser tu proyección en la empresa, un profesional en el que debes invertir tiempo, TU TIEMPO, para que aprenda, para que disfrute con su trabajo y esa inversion que haces termine siendo un profesional más en tu equipo.

Sé que es fácil decirlo pero puedo estar orgulloso de haber tenido en Wiseri compañeros que han crecido con nosotros, que su curva de aprendizaje ha sido muy buena y que recomendaría con los ojos cerrados a cualquier empresa. Han sido tratados como trabajadores de igual a igual, con responsabilidad justa y con el tiempo dejándoles solos porque veías que ya te lo pedían. Por lo menos en la gente de mi equipo sé al 100% que fue así, y del resto creo que en la misma línea porque hemos llegado a formar una pequeña familia.

Quizás es algo más fácil en una startup que en una consultora. Aunque eso no quiere decir que una startup deba constituirse de becarios por ser más baratos. Eso es un ERROR y bien grande.

Palabros en una startup

Hasta que me embarqué en Wiseri desconocía ciertas palabras y aún hoy reconozco que algunas me cuestan un poco de seguir, sobre todo a nivel de valoración de la empresa, porcentajes, series A, B... derechos...

Una con la que me he quedado ha sido Burn Rate: cuán rápido "quemas" tu dinero en la empresa mes a mes. Es un indicador que te dirá cuándo necesitarás que alguien invierta en tu empresa porque los gastos son mayores que la entrada de capital. Algo que hacía mi madre con la economía familiar toda la vida. Es algo que tienes que controlar con mucho ojo porque una de dos, o tu empresa no es rentable y tu proyecto no tiene viabilidad o te falta inversión para alcanzar el nivel en que los ingresos son mayores que los gastos. No es necesario que ganes desde el primer día, normalmente al comienzo del proyecto y durante cierto tiempo irás con pérdidas buscando ese equilibrio y en lo que desarrollas el producto y el negocio. Lo que no puedes hacer es obviarlo o pensar que con una "pequeña" ronda puedes salir adelante. Sobre todo es duro llegar a solicitar esa ronda porque en cada ronda pierdes un poco de tu hijo, das porcentaje de la empresa a cambio de dinero. Tienes que hacer muy bien los números para saber cuánto cedes y por cuánto dinero para no tener que hacer rondas muy próximas. Quizás lo mejor es tener bien pensados los números, creer en tu proyecto y ceder % tanto como sea necesario para tener el dinero que te hace falta para conseguir el break even (momento en que los ingresos igualan a los gastos).

Es muy importante tener estos datos mes a mes, o casi semana a semana para ver la evolución y la rentabilidad de la empresa. Al final es una inversión, los números negativos no te deben quitar el sueño salvo que no veas que la curva cambia su tendencia.

Otra de las cosas curiosas es el Exit de la empresa. Saber cuándo vas a salir, o como los inversores te dicen, cómo van a recuperar la inversión que van a hacer. Evidentemente repartir dividendos a fin de año está muy bien, si los hay... pero lo normal es que las cuentas salgan de tal manera que los beneficios se reinvierten en la empresa para fortalecerla y hacer que valga más...¿entonces qué? Pues evidentemente podemos esperar que venga Facebook y pague algún billón por tu pequeño proyecto y te puedas retirar para ser un nuevo Business Angel ;)

A mi personalmente me chocó mucho hablar de este tema cuando aún no habíamos empezado con nuestro proyecto. Era como hacer castillos en el aire y yo no estaba acostumbrado. También he llegado a la conclusión que si te entras sólo en el exit es un error, es como ser infiel a un proyecto en el que crees y estás super enfocado en él, es como si pensaras en ponerle los cuernos sin haber llegado a intimar aún.

Ayudas I+D en España

Iba a desarrollar este punto pero creo que ya no tiene sentido. Con las últimas medidas del Gobierno está claro que estamos más cerca de África que de Europa. Aunque tengo que avisar de una cosa: nos lo tenemos merecido. Somos un país en que se ha instaurado la cultura de la subvención y de que papá Estado ponga el dinero por mi y encima casi gratis. Es curioso la cantidad de proyectos que grandes consultoras han ¿realizado? en base a ayudas públicas. Proyectos que luego no han salido a la luz porque en algunos casos no se han ejecutado, porque 2 meses antes de cerrar el proyecto se hace la documentación para justificar el gasto. Es una vergüenza, y como son proyectos de I+D el resultado es que la I de Investigación pesa sobre la D de Desarrollo: se investigó y no ha habido resultados positivos. Ale, y todos satisfechos.

Yo he vivido eso muy de cerca y os puedo asegurar que se me cae el alma a los pies. Lo que han trincado algunos sin dar resultados... en fin.

Lo curioso de todo esto es que con las nuevas lineas del Gobierno sólo podrán acceder las grandes consultoras a esas ayudas y no saldrá nada de ellas. En cambio hay pequeños negocios que no necesitan ayudas tan grandes, que con una décima parte podrían desarrollar su idea y contribuir al desarrollo del país pero para ellos no llega nunca ese dinero.

Coste de desarrollo

Sí, hemos partido que hablamos de un proyecto tecnológico, pero ¿contratamos gente o externalizamos el desarrollo? No tengo la respuesta, lo siento. Cada uno en su casa sabrá lo que quiere hacer. Evidentemente yo creo más en contratar un buen equipo y desarrollarlo internamente. ¿Por qué? Porque es tu proyecto, porque creas un equipo y si puedes cubrir los gastos seguramente es más barato que externalizar.

Si lo subcontratas es porque no tienes los medios técnicos para realizarlo, lo cual está muy bien también. Pero vete pensando que lo tienes que pagar, y como lo has sacado fuera, si quieres que se haga con la calidad e implicación que pondrías tú en ello lo tienes que pagar bien, muy bien. Y si no tienes dinero entonces asume cuales son tus posibilidades. En cambio si quieres un trabajo puntual, un módulo siempre puedes contratar a un freelance. El gasto para la empresa puede ser menor, o no, pero siempre puedes encontrar alguien de confianza que sabes que lo que pagues estará bien invertido. Eso sí merece la pena.

Conclusión

Finalmente, este post empezó con una palabra "Talento", y aquí va un consejo: si eres un desarrollador cuida tus skills, aprende todos los días, no te acomodes con una tecnología, mejora, sé el mejor o inténtalo al menos. Por ahí hablan de poner código en Github o en otros repositorios públicos para que los recruiters te busquen. Eso es una gran idea, no digo que no, pero depende de lo que busques. Yo te recomendaría más asistir a Hackatons, juntarte con amigos a desarrollar pet projects, participar por ejemplo en el AbreDatos, asisitir a eventos, relacionarte con compañeros de profesión y hablar con ellos e intercambiar experiencias.

Para mi un factor determinante para saber cómo es de profesional un desarrollador es la siguiente idea: La persona que lleva más de 3 años en el mismo proyecto sin progresión es un profesional quemado, sin alicientes y sin estímulos. Si no quiere cambiar no seré yo quien se lo haga si no ha mostrado un interés propio en hacerlo. Todos sabemos que hay proyectos y proyectos, pero he conocido gente que llevaba años en un mismo proyecto haciendo mantenimientos aunque fueran evolutivos, pero quedándose retrasado en cuanto a tecnología se refería y lamentándose de su situación. Si no eres valiente nadie va a cambiar tu vida por ti.

La mejor tarjeta de presentación es lo que alguien de al lado pueda decir de ti, siempre es mejor entrar a trabajar en un sitio porque alguien da la cara por ti que por una entrevista que suele hacer alguien de RRHH que no sabe de lo que habla (tecnológicamente hablando).

¿Y subir código a Github? Está bien porque así estarás expuesto públicamente a todo el mundo, no solo a las comunidades cercanas que he comentado en el punto anterior... pero ni todo el talento está en Github ni todos los paquetes están fuera ;)

Otro ejemplo típico es la cantidad de Head Hunters que usan LinkedIn para buscar profesionales, y la cantidad de malos Head Hunters que lo usan también. Aquellos que lanzan las campañas a todo el mundo tras una búsqueda por palabras sin mirar siquiera el perfil del candidato. Yo en estos dos años he perdido la cuenta de mensajes recibidos, y cuando les respondía que por favor miraran mi perfil y vieran que era cofundador de una empresa me respondía que avisara a mis conocidos...en fin... Por cierto, yo llevo una camiseta que dice "A mi no me llamaron de Tuenti" porque en el último año no había persona que conociera que no hubiera sido contactado por ellos, quizás sí que eran buenos y vieron que no me interesaría en cualquier caso ;)

30Apr/1233

Nuevamente pivotando

Posted by semurat

Esperanza

Pues sí, parece que mi cuerpo pide cambios cada 2 años o algo así.

No sé si me lo tendré que mirar o si es algo intrínseco en mi y generará desconfianza a la gente que me rodea o me conoce. Vivimos en una sociedad de continuos cambios, y yo me he rodeado de gente inquieta y con ganas de hacer cosas y que en estos últimos 4 años han hecho cambios importantes en su vida, tanto profesional como personalmente. Y yo no soy menos.

El caso es que llega un momento en que tu cuerpo te pide otra cosa, no sabes qué pero hay algo que te va reconcomiendo y pides un salto, quizás al vacío, quizas a algo desconocido. Y ese momento me ha llegado, como en los últimos 12 ó 14 años de experiencia profesional vuelvo a pivotar sobre mi mismo, dentro de mi inconsciencia. No es abandonar el barco en el que estoy y por el que voy a seguir luchando, sino repartir esfuerzos y salud. He estado utilizando un programa en el iPhone para ver cómo eran mis ciclos de sueño desde Noviembre y he descubierto para mi sorpresa (o no) que dormir una media de 4 horas y media no es bueno. Que dormir con ciclos que parecen una montaña rusa hacen que no descanse, que mis jornadas de trabajo no tuvieran un ritmo y que terminara el día pensando que no había avanzado no es productivo.Hace un par de años comencé un nuevo proyecto, personal y profesional en Wiseri con muy buenos socios y ahora amigos. En estos dos años hemos dejado una parte de nuestro cuerpo, de nuestra salud, nuestra vida.  Ha sido una etapa muy bonita y muy dura. He aprendido un montón de cosas sobre montar una empresa, la primera en mi caso, sobre personas  y sobre inversores, que también son personas, no lo olvidemos, que apuestan por proyectos. Hemos vivido el comienzo de la crisis y hemos puesto nuestro granito de arena para luchar contra las circunstancias que el sistema nos imponía.

Hace unos días quedé con David Bonilla para contarle algo de esto y va el cabrón y se me adelanta con su "jamacuco" y veo algo que me preocupa, me veo reflejado (aunque en menor medida y sin susto), pero el camino es el mismo. Me doy cuenta que un sueño no puede quitarte TANTO de estar con los más cercanos, con los que te quieren y se preocupan de ti. No merece la pena el precio a pagar.

Qué mejor manera de sumar que construir tu propio camino

No sé hacia donde voy ni mucho menos qué busco, sólo sé que necesito un reciclaje profesional y personal, un nuevo foco. En círculos muy cercanos ya he hablado de este giro, a otros les he dejado pendiente una conversación por Skype pero están en mi pensamiento y mientras agradezco a los primeros que se han ofrecido a echarme una mano en la medida en que puedan.

Estos dos años han servido para darme cuenta que soy un desarrollador (o programador, o geek o vete a saber qué más) que conozco mucha gente muy buena y en muchas áreas muy diferentes (desarrollo, marketing, desarrollo front end, desarrollo mobile...) y que sois unos capullos malvados por haberme mostrado todo lo que hay fuera y todo lo que me gusta y lo que desconozco. Que no se puede saber de todo y que he descubierto que la tecnología está viviendo cambios importantes que no me quiero perder, hay un giro en cómo las tecnologías se ofrecen a los usuarios y cómo hay que estar al frente de esos cambios y ser muy bueno en ello...y eso implica aprender, aprender y aprender. También tristemente hay mucho falso gurú y mucho vende humo y bocachanclas que hay que distinguir, muchas personas que te ofrecen un plátano para luego darte un palo. Pero eso es la vida en sí misma.

Este post lleva varios meses en la nevera o más bien en mi cabeza, tanto que lo he tenido que dividir en dos, este es el primero sobre mi necesidad de cambio, habrá otro sobre mi experiencia como emprendedor.
Y como sigo tardando en publicarlo, me levanto hoy con una nueva Bonilista (29 de Abril de 2012) con un mensaje, Estamos en guerra, y lindezas como esta:

Estamos en guerra contra esa inmensa masa de técnicos mansos y adormecidos, que se quejan de la situación y no hacen nada por remediarlo.

Y algo aún más importante a aplicarme a mi mismo:

Pero, por encima de todo, estamos en guerra con nosotros mismos.

Sí, yo estoy en continua guerra y en continuo enfrentamiento con uno de mis grandes defectos, intentar no desagradar a la gente y quizás hacerles oir lo que quieren oir. No les hago ningún favor a ellos ni a mi mismo. Y esto lo he vivido tan recientemente con un negocio que me han ofrecido que me he dado cuenta que casi me meto en un lio en el que no creo. Hay que ser honesto con uno mismo y si te viene alguien ofreciéndote mierda díselo, no mantengas ilusiones o falsas esperanzas.

Así que ahora vuelvo a estar delante de un largo camino, otra ilusión y renovando la cabeza de ideas y por qué no, pensando algún nuevo proyecto para sacar adelante. Ya veremos que sale o si nuestros caminos se cruzan amigos, quién sabe ;)

30Dec/115

Objetivos para 2012

Posted by semurat

Semurat

Ya estamos un año más con esta historia...si sé que no voy a cumplir ni el 50% de lo que ponga...

El caso es que como buen macho español recojo el guante lanzado por David Bonilla en su maravilloso blog y me pongo a ello.

Primeramente decir que en este blog no existe un meme u objetivos para 2011 porque estaban en el anterior, y en estado vegetativo, blog (parece que la migración no funcionó correctamente en su día). Pero pese a eso intentaré hacer un resumen o retrospectiva del mismo.

Estos fueron los puntos que me propuse:

  1. "Mejorar técnicamente, aprender todos los días algo". Evidentemente 365 días es mucho tiempo para llevar acabo esto, pero sí tengo la sensación de haber crecido este año, tanto técnicamente como a nivel de emprendedor. Soy aún un poco bisoño en este último punto pero tener un negocio y levantarte todos los días con ánimo y contento en trabajar en lo que te gusta no tiene precio. Es mucho mejor que un MBA, porque aprendes a base de leches y disfrutas más de las alegrías.
  2. "Contribuir al mundo de desarrollo de software". ¿Pero qué narices quería decir con esto? Pero quién soy yo para pretender contribuir... El caso es que este año he estado muy alejado del grupo AgileCyL, pero estoy satisfecho viendo que es un grupo que ya ha crecido y hay gente detrás que lo puede llevar a cabo y es autosuficiente para ello. Son una gente maravillosa. Quizás esa es la parte en la que he contribuido (aunque fue más en 2010). Pero como tenía una espinita clavada...me he lanzado con otros compañeros a la aventura de CyLicon Valley que espero en 2012 dar mucha mucha guerra con ello...y si estás leyendo este blog ten cuidado, algún día tendrás un email mio pidiendo que vengas a darnos un taller o una charla. En este punto anuncié post más técnicos y en un nuevo blog...este. Lo cumplí hasta febrero, luego desapareció todo
  3. "Seguir apoyando y aportando a gente en las metodologías ágiles". Contestado en el punto anterior. Por lo menos he seguido asistiendo a la CAS2011 y al AOS2011, dos citas imprescindibles para darme cuenta del largo camino que tengo por delante.
  4. "Escribir algún post en inglés". Sorry, I'm still laughing reading these words XDDDD. No comment.

Y ahora viene lo mejor...para 2012 lo que quiero es...

¡¡ SER FELIZ !!

Y para ello tengo claro una cosa: tengo que dedicar más tiempo a quien me quiere y saber diferenciar el tiempo de trabajo del de ocio para llevar una vida más sana. No tengo más objetivos este año, creo que todo lo que haga será con este fin último. Si me gusta desarrollar y eso me hace feliz, pues lo haré y alcanzaré mi objetivo, si me siento bien ayudando a otras personas, pues otro tanto de lo mismo.

Sí tengo unos objetivos personales que llevaré acabo pero voy a ir paso a paso, ya he aprendido en tantos años que lso grandes sueños se quedan en eso y los pequeños objetivos llevan a grandes triunfos.

Bien, en el post del año pasado hablé de ciertas personas y si alguno tiene curiosidad verá que no me he equivocado en algunas de las frases que puse, sobre todo recuerdo la de David y la de Enrique Comba...uno ya es Embajador de Atlassian en España y el otro ya ha aterrizado en España con Path11.

Y este año sólo nombraré a las personas que creo que más me han aportado, en lo humano y profesionalmente:

  • Laura Morillo-Velarde: mi compañera de desarrollo en Wiseri y mi "Pepito Grillo" de las metodologías ágiles y las buenas prácticas... y aún tengo que hacerla mucho más caso ;) A ver si no cojo mi mala influencia y retoma su blog...puede que se un objetivo de empresa para 2012, jejeje
  • Javier Santana: un crack en Valladolid y me entero este año!!! Nuestro espartano en CyLicon Valley y uno de los tipos que dicen verdades como puños, aunque a veces te deje a cuadros :P Tampoco os pedais las joyas que deja en su blog.
  • Alvaro García Loaisa: quien iba a decir que después de tanto tiempo compartiendo comedor íbamos a terminar maquinando eventos y talleres con un mismo objetivo. Es la persona junto con Amalia que más motivación tiene y más ánimos para movilizar al personal, y un gran desarrollador preocupado por su profesión. Podéis leerlo aquí
  • Félix López: si no seguís a este tipo sois unos LOSERS, pero así, en grande. Va a dar mucho que hablar, ya ha terminado el año dando un salto importante en su carrera profesional y física porque se ha marchado a NYC a trabajar en ShuttleCloud .Para mi, tanto él como Javi Santana son los Zipi y Zape del desarrollo hispano y si no preguntad a JM Navarro, y estoy super orgulloso de compartir con ellos CyLicon Valley y seguro que muchas más cosas que somos jóvenes ;)

Así que si el año pasado ya os dí unos nombres, este año no soy menos y ya veréis cómo no me equivoco.

Tagged as: , 5 Comments
28Feb/116

Test Unitarios con Groovy y Grails

Posted by semurat

Como decíamos ayer...seguimos con la implementación de test en el entorno Grails / Groovy y hoy nos hemos enfrentado a otro reto: luchar contra el monstruo de la JVM sobre la que se ejecuta el código de Groovy.

Origen del problema: lentitud

¿Cuál era el problema original? Que tristemente los test que corren en Grails tardan demasiado tiempo, lo cual para un entorno de desarrollo bajo TDD es bastante contraproducente, no puedo estar tantos segundos esperando a que se resuelvan las dependencias de Grails para poder hacer un simple test unitario que debe ejecutarse en milisegundos, no en decenas de segundos.

Grails: framework rápido de generar y lento de ejecutar

Descubrí los días pasados una opción para que los tests no tardaran tanto con Grails, y era con la ejecución del comando grails interactive que arranca el Grails CLI (script runner) en modo interactivo, lo cual traducido quiere decir que te deja la JVM en ejecución mientras lanzas comandos de grails como la ejecución de los tests. Con esta herramienta conseguimos que no tarde en levantar la JVM y mejoramos los tiempos de ejecución de los comandos. Pero esto que parece tan bonito tiene un problema, según va pasando el tiempo y vas lanzando la ejecución de tus tests, la velocidad de los mismos empieza a crecer y tardar más, como si hubiera algún memory leak incontrolado, quizás por algún mal uso del Garbage Collector por parte de Grails. Como se va consumiendo la Heap Memory  el GC no entra a hacer bien su trabajo, el rendimiento del sistema cae y penaliza la ejecución de los tests. Claro, si estás todo el día haciendo TDD esta solución es como la de apaga el motor del coche cuando se te calienta, un apaño que no arregla el problema de fondo.

¿Groovy o Grails?

Entonces, analizando lo que tenemos: un lenguaje dinámico que ya de sí es lento y pesado, una JVM que gestiona la memoria como todos sabemos y con sus problemas y un framework de desarrollo que es bastante pesado de levantar cada vez que quieres hacer una prueba (vale, alguno me dirá que puedo hacer cambios en el código, menos en las clases del dominio y que Grails los coge en caliente...sí, ya, pero estoy hablando de test y TDD, no de hacer "pruebas a ver qué pasa").

Con esos 3 elementos hay uno que podemos intentar obviar...el framework. ¿Para qué necesito todo Grails para hacer test unitarios sobre un servicio? ¿Me aporta algo a mayores usar el GrailsUnitTestCase? Sencillamente, no. Intentemos quitar esas dependencias del framework y hacer TDD con los artefactos que me da Groovy, es decir vayamos una capa más abajo y no levantemos la JVM con la aplicación y la resolución de todas las dependencias.

La solución

¿Cómo hacemos ahora el test? Usando GroovyTestCase. Sólo necesitamos poder crear Stubs para los objetos que necesita nuestro servicio y así poder probar este ante distintos casos de prueba.


class CategoryServiceTests extends GroovyTestCase {
    def categoryDAO
    def categoryService

    protected void setUp() {
        super.setUp()
        categoryDAO = new StubFor(CategoryDAO)
        categoryService = new CategoryService()

    }

    void testNoCategoriesEmptyTagCloud() {
    		categoryDAO.demand.allCategories(){[]}
    		categoryDAO.use {
    			categoryService.categoryDAO = new CategoryDAO()
	    		def tagCloud = categoryService.tagCloud()
	    		assertTrue  tagCloud.isEmpty()
    		}
    }

    void testAnyCategoryMightHaveOffers(){

		categoryDAO.demand.allCategories(){[new CategoryBase(name:"Java")]}
		categoryDAO.demand.jobOffersCountBy{category -> new Integer(1)}
		categoryDAO.use {
				categoryService.categoryDAO = new CategoryDAO()
		    		def tagCloud = categoryService.tagCloud()
		    		assertEquals 1, tagCloud["Java"]
		}
    }

    void testSomeCategoriesHaveOffersAndOthersNot(){

    		def categoryJava = new CategoryBase(name:"Java")
    		def categoryPython = new CategoryBase(name:"Python")
		categoryDAO.demand.allCategories(){[categoryJava, categoryPython]}
    		categoryDAO.demand.jobOffersCountBy(categoryJava){category -> new Integer(1)}
    		categoryDAO.demand.jobOffersCountBy(categoryPython){category -> new Integer(0)}
		categoryDAO.use {
				categoryService.categoryDAO = new CategoryDAO()
		    		def tagCloud = categoryService.tagCloud()
		    		assertEquals 1, tagCloud.size()
		    		assertEquals 1, tagCloud["Java"]
		}
    }
}

Como estamos testeando la clase servicio, hemos definido un Stub de CategoryDAO para simular su comportamiento.

class CategoryDAO{
	 List allCategories(){
		throw new Exception("Not implemented")
	}

	 Integer jobOffersCountBy(category){
		throw new Exception("Not implemented")
	}
}

Este DAO además me permite aislarme de la capa del modelo, ya que en frameworks como Grails nos empujan a hacer código un poco feo y potenciando el famoso modelo anémico que hay que evitar y a veces no podemos.

Vale, ya tenemos el test escrito, y ahora ¿cómo lo ejecutamos? Parece que en Groovy es sencillo, solo hay que invocar a groovy sobre la clase de Test y ya está. Pero ahí es donde entra el contexto en el que estemos trabajando y las dependencias entre las diferentes clases que tengamos. Mi servicio no tenía ninguna dependencia extraña, pero la clase para la que creamos el Stub está ligada a las clases del dominio, y necesitaba de ciertas librerías externas que en Grails teníamos pero que en nuestro test aislado del framework no las teníamos al alcance.

No hay que preocuparse, para este problema una solución sencilla y que además nos va a permitir mejorar nuestros procesos de lanzamiento de Test. Definimos un script para lanzar el test y además le pasamos en el CLASSPATH aquellas dependencias que tenga nuestro test. Evidentemente cuantas más dependencias con otras librerías tenga nuestro test más lenta es su ejecución porque la JVM tiene que arrancar y cargar las librerías.

groovy -classpath /Users/semurat/Proyectos/sample/grails-app/services/:/Users/semurat/Proyectos/sample/src/groovy CategoryServiceTests.groovy

Mejoras futuras

¿Qué posibilidades nos da esto? Poder estudiar cómo, cuando guardemos una modificación, se lance este script y estar continuamente lanzando los test en nuestra máquina.


24Feb/110

Stubs y metaclases en Groovy

Posted by semurat

Dentro del tour que Carlos Ble está realizando por distintas empresas de España, he tenido la suerte y no quiero dar envidia al resto, de poder llevar Wiseri hasta Tenerife, lo cual es un valor añadido para Wiseri, por supuesto de compartir esta experiencia con Carlos en un entorno incomparable.

En nuestra primera misión con el código nos hemos enfrentado a un reto al diseñar con TDD, en vez de hacerlo con un diseño Down-Top nos hemos decantado por un diseño Top-Down, es decir, hemos definido unos escenarios y hemos escrito unos ejemplos que expliquen cada caso que tenemos. Como el desarrollo es en Grails y Groovy pensamos en empezar con los test unitarios de la capa de servicio, y posteriormente pasar al controlador para finalizar con test de integración. Esta era la idea original pero nos hemos decantado con la otra aproximación, empezando con un test de integración del controlador aunque de ámbito tan reducido que parece unitario.

La idea es generar una nube de Categorías, dándose dos casos, que no haya ningún resultado o que tengamos resultados, de manera que renderizaremos una vista u otra dependiendo del caso. Genial!!! No parece complicado, manos a lo obra!!

El primer caso fue muy sencillo de implementar el test, pero Carlos quiso ir más allá y empezamos a usar stubs para simular el comportamiento del servicio que se invoca desde el controlador. Tiene su lógica, al tener que probar el comportamiento del controlador en 2 casos diferentes. Y ahí comenzó nuestro dolor de cabeza...no queríamos usar los mocks que nos proporciona Grails, sino implementarlos nosotros.

Como acababa de estar en el Taller de DSL del gran Alberto Vilches en el SpringIO 2011 propuse usar la implementación con closure  para modificar el comportamiento del servicio en cada test y así probar de manera independiente el controlador. Todo iba bien y el código quedaba como vemos a continuación:

void testRenderEmptyViewIfNoOffers() {
    CategoryService.metaClass.tagCloud={
       [:]
    }
    this.controller.renderTagCloud()
    assertEquals 'wrong view was rendered', 'empty', this.controller.modelAndView.viewName
}

void testRenderTagCloudViewIfThereIsACategoryWithOffers(){
     CategoryService.metaClass.tagCloud= {
           ["Java":1]
     }
     this.controller.renderTagCloud()
     assertEquals 'wrong view was rendered', 'tagCloud', this.controller.modelAndView.viewName
}

Así estaba genial, la idea era muy buena...hasta que lanzamos los test, bueno, el segundo test y vimos que sólo nos pillaba la nueva implementación con la closure del primer test, no hacía no caso de lo que habíamos modificado  en el segundo test, con lo que el test estaba en rojo, pero rojo intenso.

Y ahí comenzó nuestro dolor y peregrinaje en el desierto... quizás lo fácil habría sido un telefonazo a Alberto Vilches, pero como soy muy cabezota estuvimos dando vueltas, intentando modificar aún más el comportamiento de nuestro servicio sin un resultado óptimo.

Y como la constancia al final tiene su premio, descubrimos en esta dirección cómo hacerlo y cuál era el origen de nuestros problemas.

Todo era cuestión de "resetear" la clase a la cual habíamos modificado su comportamiento con un método anónimo mediante closure.

protected void tearDown() {
    super.tearDown()
   resetMetaClass(CategoryService)
}
// http://archive.codehaus.org/lists/org.codehaus.grails.user/msg/408cc93f0904160210v7f4df673tc1e670dc2ece9635@mail.gmail.com
static void resetMetaClass(classes) {
    classes.each {clazz ->
          def emc = new ExpandoMetaClass(clazz, true, true)
          emc.initialize()
         GroovySystem.metaClassRegistry.setMetaClass(clazz, emc)
    }
}

La clase ExpandoMetaClass nos permite, dinamicamente, añadir metodos, constructores, propiedades y métodos estáticos usando una sintaxis de closures.

La sintaxis del constructor tiene 3 parámetros, la clase sobre la que se aplica la MetaClass, un boolean para indicar si se registra dentro de MetaClassRegistry y un último parámetro boolean para indicar si se permiten cambios tras la inicialización. Tras llamar al constructor se inicializa y finalmente se modifica el registro para dejarlo con su valor por defecto.

Al final es muy sencillo, ha costado encontrarlo pero nos permite este mecanismo no pegarnos tanto con los mocks, ni mockFor del framework para manejar los stubs para nuestras pruebas.

Tagged as: , , No Comments