Page Objects con PHPUnit y Webdriver

A finales del año pasado me llegó la posibilidad de colaboración a modo de consultoría con Funidelia, un comercio electrónico de disfraces. Un comercio electrónico que además va como un tiro, por cierto.

Me contactaron para echarles una mano para empezar con el testing funcional (o de sistema, o end-to-end, o…). Ya que al parecer intentaron en el pasado ponerse con ello pero, como ocurre en muchas ocasiones, el día a día de una startup no permite que el equipo técnico pueda focalizarse en ello.

Así que tras una reunión inicial y alguna otra conversación teníamos claro que mi papel era sentar unas bases sobre las que ellos pudieran seguir.

¿Cuáles eran esas bases?:

  • Implementar casos los tests automáticos para la parte más crítica del negocio: los diferentes puntos dentro del proceso de compra.
  • Saber cuanto antes cuando se rompe un test. Así que se pueda lanzar correctamente desde un servidor de integración continua (que en su caso era un jenkins) sobre entornos de desarrollo.
  • Además del entorno de desarrollo que pudieran lanzar contra entornos de staging, o incluso producción. Teniendo en cuenta que la misma base de código del comercio electrónico se ejecuta en diferentes instancias y configuraciones (por país).
  • También se debían lanzar los tests con diferentes navegadores, es crítico que funcione correctamente con todos lo navegadores mayoritarios.
  • El lenguaje de programación a utilizar iba a ser PHP, ya que es el utilizado por el equipo.

Una cosa que estuvimos hablando fue el que los tests sólo cubrirían los escenarios optimistas del proceso de compra, esto es cuando se supone que al usuario todo le va bien y termina con su compra de disfraces hecha. No sólo para lo que yo iba a hacer, si no también para cuando el equipo siguiera evolucionando las baterías de tests. Al final son tests lentos, frágiles y mantenerlos tiene bastante coste, pero luego volvemos a ello.

Las herramientas:

Hacía mucho que no programaba en PHP y no estoy para nada al día de sus novedades, pero para esto estábamos de acuerdo que no creíamos que iba a ser un gran problema.

Aunque no estuviera muy al día sí tenía referencias de cosas como composer para gestionar las dependencias y era el punto de partida.

En cuanto al framework de testing se me pasó un momento por la cabeza el cacharrear con behat, pero como al final iban a ser tests sólo para los programadores me parecía añadir una indirección que no aportaba nada; así que tiramos a lo seguro con PHPUnit, que ir con algún framewrk xUnit es ir sobre seguro.

Para el lanzamiento de acciones de navegador también tenía claro la elección con Selenium Webdriver y el cliente PHP implementado por la gente de facebook.

Mientras para que para el soporte de ejecución frente a diferentes entornos, monté algo de código a medida para poder cargar configuraciones de ficheros json a partir de un parámetro enviado al comando de ejecución de la batería de tests.

Page Objects:

Y ya respecto a los propios tests, como escribía algo más arriba, los funcionales suelen ser considerados frágiles y lentos.

Decimos lentos para el contexto de que no nos sirven para dar feedback rápido de si algún cambio que hayamos introducido en el código ha roto algo, si los intentas usar para ello serán una tortura para tu flow. Si a alguno no le suena la Pirámide de Test siempre puede informarse de ello en la web de Fowler.

Pirámide de Test

Y decimos frágiles principalmente porque cualquier cambio de maquetación html por pequeño que sea puede romper el test: un texto, un class, un id… Así que, salvo que la UI no evolucione, suelen resultar caros de mantener frente a otros tipos de tests.

Una forma de abaratar bastante el mantenimiento de esos tests es el uso Page Objects. De modo que para cada página (aunque también podríamos tener Page Objects de elementos comunes, como quizás un menú de navegación) que queremos que participe en los tests abstraeremos sus detalles de implementación para utilizarlo como un objeto en cada caso de test, reduciendo de esta manera la duplicidad de código y mejorando la legibilidad de los propios tests.

En los Page Objects expondremos tanto métodos que crean/llevan a otros Page Objects como otros que lanzarán acciones para que sean ejecutadas en el navegador (un click, completar un formulario…) y de los que opcionalmente esperaremos algo en el retorno.

Además en mi caso implemento los Page Objects con la responsabilidad de los asserts en el propio Page Object. Ahí decido lo mucho o poco que quiero acoplarlo a la maquetación exponiéndolo como un assert con un lenguaje más de negocio. Esto lo comento porque al implementar Page Objects existen 2 vertientes ligeramente diferentes: incluir los asserts o proveer un modo para que el test sea el responsable de cómo se le hacen los asserts y así separar responsabilidades. El propio resumen final que enlazo, por lo general, desaconseja lo asserts en estos objetos; aunque a mi por el momento no me ha resultado problemático el hacerlo y se adapta más a mi gusto.

Y ya desde un punto de vista más práctico y sin meterme en detalle, este es como quedaría test de añadir un producto al carro de la compra:

Como se puede ver en el código, se mantiene encapsulado entre esos objetos. Podría cambiar completamente la maquetación de la UI y tendríamos que cambiar sólo la implementación de los Page Objects (que no es poco). Otro tema es que, por razones de diseño o negocio cambiara la lógica de navegación, claro.

Elecciones al Congreso en Arredol

Como publiqué en twitter el mismo domingo del 20-N (el día de las elecciones, vamos :P), colaboré con Arredol, un pequeño diario online publicado en aragonés, desarrollando las gráficas de los resultados electorales a las elecciones del congreso español.

Fue un desarrollo exprés, ya que tenía otros compromisos que no podía dejar de lado. Fueron unas 6 o 7 horas de trabajo a tope ese mismo fin de semana, pero me apetecía colaborar por fin con algún medio, aunque fuera tan pequeñito como lo es arredol :).

Herramientas utilizadas:

  • El API que puso a disposición El País. Que básicamente hizo el trabajo que según los que defendemos el OpenData debería ser responsabilidad del Ministerio del Interior, poner a disposición de cualquier persona o entidad esos datos de forma estructurada para poder procesarlos.
  • El API de Google Charts para las representaciones gráficas. No pude adaptar los colores por partido por las limitaciones que tiene, o al menos no logré dar con la solución.
  • En el lado del servidor PHP y simplexml para procesar la información de El País. Básicamente por que el hosting de arredol sólo soporta php, no por otra cosa en especial.

Elecciones en arredol.com

Como podréis comprender, por haber sido un pequeño desarrollo hecho a toda prisa, el código en general es muy mejorable; pero el resultado cara al usuario creo que no está del todo mal.

Seguramente fuera una solución muy alejada de las herramientas de visualización de algunos grandes medios de comunicación, con una posibilidad de interacción mucho mayor. Pero en Aragón quizás fuera de lo mejor, cosa que casi me entristece.

No vi que tuviera mucho que envidiar a lo que vi que hicieron por ejemplo en la web de Heraldo, y no digamos de El Periódico de Aragón donde no vi nada especial para la ocasión… Supongo que no dedicarían muchos esfuerzos…

Cursos del CTA 2008-2009

Hoy mismo, me ha llegado un email avisándome que ya está disponible el calendario de cursos del Centro de Tecnologías Avanzadas de Zaragoza.

En el calendario del programa TIC hay cursos de administración de Linux y Windows Server, networking(estoy hablando de redes :P), seguridad, gestión de proyectos…

Pero cómo era de esperar los primeros que estoy mirando son los de programación :), y parece que se repiten bastantes del año pasado. De los que he estado viendo, me interesan:

El de Java ME y el de Spring+Hibernate+Struts2, el primero salirme un poco del sólo web y el segundo más que nada por ver Struts2. Otro que me parece medio interesante es el de Java EE para ver algo de JMS, EJB3 e incluso de Struts2 que además incluye gratuito el examen de certificación SCJP(¿no sería mejor un curso de preparación para esto?); pero me parece un poco coñazo ver Servlets y JSPs.

Habrá que ver si puedo sacar tiempo durante 2 o 3 semanas para asistir a alguno de estos curso o me vuelvo a quedar sin hacer ninguno, ya que parece que los autónomos también podemos inscribirnos 🙂

También hay algunos cursos más de Java, además de PHP+MySQL(también incluye examen de certificación a PHP5) y de .Net; o incluso de CICS y SAP(si lo que quieres es ganar más dinero programando…).

Aún siendo cursos de programación que, además de ser gratuitos, no sacan mala pinta; para mi falta algún curso sobre algún framework algo más novedosos/ágil en cuanto a desarrollo web tipo Ruby on Rails, Grails, Zend Framework, Django, Symfony… aunque en el tiempo que sigo los cursos que salen del CTA, no suelen destacar por ser early adopters y sí por ser bastante enterprisey.

Por cierto, que en el boletín de Septiembre, ya salen los cursos disponibles para octubre en los que ya se puede hacer la pre-inscripción.

Actualizar InstantRails a PHP5

En el momento empecé a trabajar con Ruby on Rails, elegí la opción de instalar uno de esos paquetes precocinados para instalar y listo, en este caso, sin duda, InstantRails. Como ya trae instalado PHP, desinstalé XAMPP por no andar matando procesos, además de que para qué quiero dos de estos paquetes casi equivalentes.

El problema es que instantrails viene con PHP4 y no con PHP5, como iba a estar un tiempo sin trabajar con PHP lo dejé así(aparte de un micro-proyecto que puede correr perfectamente con PHP4), hasta que un amigo me pasó un pequeño desarrollo usando el soporte OO de PHP5 para que le pegara una ojeada a un par de cositas, lo que me ha obligado a andar cambiando configuraciones.

En fin, los pasos para actualizar son estos:

  • Para empezar debemos descargar el .zip de la última versión de php.
  • Renombrar la carpeta de instantrails php a php4, por si acaso.
  • Extraer el contenido del .zip a una carpeta php dentro de instantrails.
  • En conf_files/httpd.conf, modificar LoadModule php4_module “${path}/php/php4apache.dll” por LoadModule php5_module “${path}/php/php5apache.dll” y AddModule mod_php4.c por AddModule mod_php5.c.
  • En conf_files/php.ini, modificar extension_dir = “${path}\php\extensions\” a extension_dir = “${path}\php\ext\”
  • Por último reiniciar apache

Y ya hemos actualizado a PHP5

Desarrollador Independiente

Es lo que soy a partir de hoy, tras un último día de trabajo un poco raro he dejado ya Net2u y aprovecho esta semana para cerrar algún tema pendiente, para empezar la semana que viene completamente centrado.

Es algo que desde que empecé a estudiar esto de la informática siempre me ha rondado por la cabeza, y ya con bastante experiencia, muchas ganas y mi punto de inconsciencia, creo que ya ha llegado el momento de lanzarse a intentarlo ahora como autónomo y, si todo va bien, porqué no crear una empresa en el futuro.

¿Tendrá algo que ver el ya conocido como el virus de jaiku?, sin duda, eso se parece cada vez más a la mafia de PayPal XD.

Por ahora empiezo bien, el verano ya lo voy a tener ocupado completamente. Tendré que dedicarle tiempo al Summer of Code que empezó oficialmente ayer, a un proyecto que está en el horno y… bueno esto que lo hagan público otros ;). Aparte tengo por ahí un par de pet-projects pendientes que por el momento van a tener que esperar.

A nivel de tecnología, hoy por hoy puedo desarrollar proyectos en PHP y Java.
Por el momento PHP lo tengo pensado sólo para proyectos pequeños que necesiten un hosting económico, aunque quizás acabe ojeando algún framework por si acaso y tienen todos los números CodeIgniter o Zend, por su sencillez probablemente sería el primero.
En Java los frameworks que conozco bastante bien son Struts(para mantenimientos/ampliaciones), JSF(MyFaces) y Grails, es probable que tal y como me vaya descargando estudie Spring MVC.
Otro de los frameworks que tengo que estudiar es Ruby on Rails, este sí que será en breve, hace un tiempo que hice mis primeras pruebas con este framework, me pareció interesante, y he de decir también que el soporte de NetBeans a Ruby y RoR me pareció bastante bueno.

Por otro lado, tras el verano, tengo pensado empezar a mover en serio jLibrary y a dar soporte para integraciones con otras aplicaciones o para desarrollar aplicaciones usándolo como base.

Muchos planes y sólo una persona, sólo sé una cosa, que no me voy a aburrir :).

Cambio de Theme

Como se puede ver, por fin he cambiado el theme de wordpress, después de navegar durante un rato en el theme viewer, me he quedado con el theme simple-tech-10. Quería una plantilla a tres columnas, una para el menú de wordpress, otra para los widgets y otra para el contenido, así no recargar demasiado una columna; y que además mantuviera las columnas al entrar a ver los posts, cosa que no hacía el clásico Kubrick.

De todos los themes que he ido viendo, este ha sido el que más me ha convencido. Eso sí, me han quedado muchos por ver, que en el theme viewer de wordpress hay demasiados como para verlos todos. Una vez puestos los widgets, sólo he tenido que hacer algún ajuste a la hoja de estilos para que no descuadraran el diseño y listo.
¿Opiniones/críticas?

Las vistas de ZendFramework

Últimamente, estoy sacando algunos ratos para desarrollar una pequeña web para ir probando el ZenFramework. Hasta el momento he encontrado cosas que me han gustado y que no.

La Convention over Configuration te ahorra el pelearte con ficheros de configuración (como la mayoría de los frameworks más conocidos de php), el patrón ActiveRecord y la cantidad de componentes que trae de serie(por lo que parece sino todos, la mayoría vienen “reciclados” de PEAR).

Lo que no me ha gustado ha sido la combinación de los componentes Zend_View y Zend_Controller para la vista, que es un sistema de plantillas basado en php.
El primer problema que encuentro es que no hay forma de definir una página maestra, por lo que para poner por ejemplo una cabecera y un pie hay que hacer algo parecido a los includes.

echo $this->render(‘cabecera.phtml’)
…codigo…
echo $this->render(‘pie.phtml’)

El segundo me parece todavía más molesto, al ser php combinado con html, se complica mucho el código de las plantillas. Y si para un programador le puede ser ya difícil de seguir donde se habre y cierra un foreach o un if, un diseñador o maquetador puede pasar un rato divertido.

En conclusión, que acaba pareciendo código spaghetti. Eso sí,parece que se puede utilizar Smarty como motor de plantillas, con el que en su día no estuve demasiado cómodo trabajando y no me motiva demasiado probarlo.

Toma de contacto con eclipse PDT

He estado trasteando un poco la versión 1.0 de eclipse PDT, y he visto que en unos meses ha mejorado muchísimo, hasta el punto que a partir de ahora va a sustituir al plugin PHPeclipse que llevaba bastante tiempo utilizando. La verdad es, que por lo que he estado viendo, este puede llegar a ser el IDE por excelencia para desarrollar con php, si Zend no hace algo para evitarlo (con su Zend Studio mientras sea de pago lo tienen difícil) y todavía nos quedará por ver como queda el plugin para NetBeans.

El editor funciona perfectamente, cargándote las ayudas para clases, métodos y funciones, pudiendo acceder también a sus implementaciones sin tener que volverte loco buscando en qué fichero tengo la clase-método-funcion X, cosas que hacía PHPeclipse un poco a su manera, y con PDT funcionan a la perfección.

Personalmente pienso que el editor de código es lo más importante en un ide, que al final es con lo que más nos peleamos los programadores, pero también existen otras características destacables:
– Soporte para debugging.
– Opción a ver qué tipo de objetos o variables devuelve un método.
– Poder indicar si el código de un proyecto es php4 o php5.
– Posibilidad de crear templates generadores de código asociados con sus alias, de serie vienen bastantes creados.
– Ayudas también para escribir en ficheros html y css.
– Etc.

A ver si hago un hueco y pruebo un poco más a fondo el ide, aprovechando que quiero trastear también el Zend Framework y tengo alguna pequeña idea que me ronda por la cabeza.