Integración continua con PHP (II). Pruebas unitarias.

27/12/2008

En el proceso de construcción del software la implementación y ejecución de pruebas unitarias es, entre otros, uno de los pilares fundamentales. La creación de tests unitarios y su ejecución automatizada permiten dotar a dicho proceso de construcción del software de confianza y calidad, permitiendo éstos parámetros, a su vez, la puesta en marcha de metodologías de trabajo ágiles.

En la actualidad existen en el mercado del software libre multitud de frameworks que facilitan la tarea de implementación y ejecución de pruebas  unitarias, concretamente, para entornos de desarrollo basados en tecnología PHP nos encontramos con frameworks como PHPUnit o SimpleTest, aunque también existen frameworks de desarrollo, como Symfony, que proporcionan su propia suite de testing.

En el presente post nos centraremos en PHPUnit y su integración con Phing para un proyecto basado en Symfony 1.0 (instrucciones de instalacion).

Para instalar PHPUnit ejecutaremos las siguientes instrucciones (se supone que tenemos instalado pear):

  • pear channel-discover pear.phpunit.de
  • pear install -a phpunit/PHPUnit

Una vez instalado PHPUnit, crearemos un proyecto symfony (con la correspondiente aplicación y módulo), para este post vamos a crear una clase Contact con su correspondiente test ContactTest. Para ejecutar los tests nos situaremos en la carpeta “/lib/classes/” del proyecto y ejecutaremos la siguiente instrucción:

  • phpunit *Test.class.php

Pero, cómo podemos automatizar la ejecución de las pruebas, es en este punto donde entra en juego la herramienta de la que hablamos en el anterior post, phing, con ella podemos declarar una nueva tarea que ejecutará todas las pruebas unitarias que hayamos implementado para la aplicación que estamos desarrollando. veámoslo.

En primer lugar tendremos que crear un nuevo fichero build.xml con el que construiremos nuestra aplicación, este fichero contará, entre otras, una tarea de ejecución de pruebas que será algo como lo siguiente:

<target name=”test”>
<phpunit2 haltonfailure=”false” printsummary=”true”>
<batchtest>
<fileset dir=”./lib/classes/”>
<include name=”*Test.class.php”/>
</fileset>
</batchtest>
</phpunit2>
</target>

Con esta tarea le estamos indicando a phing que queremos ejecutar todas las pruebas que se encuentran en el directorio “lib/classes/”, que no queremos que se pare si encuentra alguna prueba no satisfactoria y que queremos que se muestre por pantalla el resumen, a su vez existen otras tareas ligadas a phpunit que permiten obtener reportes más completos como gráficas estadísticas, niveles de covertura, etc.

Como podemos ver la integración de phpunit en phing nos proporciona una forma ágil de ejecutar tests unitarios obteniendo los reportes oportunos.

Aquí dejo el proyecto symfony con el fichero build.xml

En esta ocasión voy a optar por no escribir una frase célebre que más o menos resuma la idea que se escondía detrás de este post, como es mi costumbre, sino que voy a aprovechar para felicitaros a todos estas fiestas y desearos un feliz comienzo de año 2009.


Integración continua con PHP (I)

27/09/2008

Para una empresa que tiene en el Desarrollo de Software una parte importante del núcleo de su negocio disponer de todas las herramientas necesarias para facilitar el desarrollo (IDE´s, licencias de software, entornos de preproducción, etc) de su actividad supone una ventaja respecto a sus competidores.

Hoy vamos a comenzar con el primero de una serie de posts cuyo objetivo final es conseguir configurar un sistema de integración continua para proyectos ejecutados con tecnología PHP. Un entorno de integración continua es una de esas herramientas que facilitan y mejoran todo el ciclo de vida de un producto software.

Un sistema de integración continua está compuesto por una serie de piezas que dispuestas de una cierta forma permitirán realizar integraciones automáticas frecuentes del proyecto, con todas las ventajas que ello supone. Estas piezas que necesitamos son, como mínimo:

  • Sistema de control de versiones (SVN).
  • Sistema de construcción de proyectos (Phing).
  • Servidor de integración continua (Xinc).

En este primer post solo vamos a cubrir las dos primeras partes del sistema de integración continua: sistema de control de versiones y sistema de construcción de proyectos. Para el sistema de control de versiones vamos a utilizar Subversion y como sistema de construcción de proyectos vamos a usar Phing.

Como supongo que todos conocemos lo que es un sistema de control de versiones como Subversion hablemos de Phing. Phing es un sistema de construcción de proyectos basado en Apache Ant que permite automatizar, a través de la descripción en un fichero XML, tareas como: ejecución de pruebas de unitarias, generación de documentación, comprobación de estándares de codificación, generación de “distribuibles”, etc.

Lo primero que haremos será llevar a cabo la instalación del sistema de control de versiones para ello podemos seguir los pasos de pasos de la siguiente guía.

Una vez instalado el sistema de control de versiones pasaremos a instalar Phing, (suponiendo que tenemos ya tenemos instalado PHP) para ello seguiremos los siguientes pasos:

  • apt-get install php5-dev, con este paquete podremos instalar phpize que nos facilitará la instalación de Xdebug.
  • apt-get install pear, PEAR es un sistema de distribución de componentes PHP.
  • pear channel-discover pear.phing.info
  • pear install -a phing/phing, con la opción -a haremos que se descarguen todas las dependencias de Phing.
  • pear install VersionControl_SVN-0.3.1, debemos instalar este paquete porque la configuración por defecto de Pear siempre instala la versión “estable” y para trabajar con phing necesitamos esta versión alpha.

Bien, ya tenemos instalado nuestro sistema de construcción de proyectos, ahora veamos cómo funciona. Para comenzar, una prueba simple (más adelante lo complicaremos más). Supongamos, para no ser demasiado simplista, que estamos desarrollando un proyecto con Drupal y lo tenemos versionado, un nuevo recurso se incorpora al proyecto para poder comenzar a desarrollar lo único que tendrá que hacer es instalar Phing y tras descargar el fichero build.xml

<?xml version="1.0"?>
<project name="drupal" default="dev" basedir=".">
    <target name="dev" depends="checkout"/>
    <svncheckout
       svnpath="/usr/bin/svn"
       username="usuario"
       password="contraseña"
       repositoryurl="http://localhost/svn/portal-drupal/trunk/"
       todir="/home/user/workspace/Test"/>
</project>

Tras hacer esto ya tendrá disponible el entorno de desarrollo listo para comenzar con actividad.

Aunque se presentado un ejemplo muy simple las posibilidades de Phing son, como hemos comentado antes, muy ampllias y las iremos descubriendo en sucesivos posts.

La función de un buen software es hacer que lo complejo aparente ser simple. Grady Booch


Sobre los prejuicios y PHP

04/09/2008

Con la llegada de PHP5 y su orientación a objetos (la orientación a objetos que PHP4 proporcionaba no lo convertía en una opción competitiva aún) con sus modificadores de visibilidad, manejo de excepciones orientada a objetos y demás características ha vuelto a cobrar fuerza una opción que revoloteaba en la cabeza de muchos ingenieros software a la hora de seleccionar un marco tecnológico con el que modelar la solución software que le proporcionarán a sus clientes, está claro, a la luz de los hechos, que dicha opción no existe o no tiene el mismo peso en todas cabezas.

En el día a día , tanto profesional como personal, se toman muchas decisiones, de mayor o menor envergadura, en base a una serie de criterios y motivos. Muchos de estos criterios y motivos son estudiados minuciosamente para conseguir maximizar los beneficios obtenidos de tales decisiones, pero por desgracia hay otras decisiones, fundamentales para una empresa que tiene en la Ingeniería del Software una de sus áreas de negocio, como son los marcos tecnológicos con los que trabajar, que se toman en base a prejuicios e ideas infundadas. PHP es uno de esos marcos tecnológicos que cuenta con un número mayor de ellas:

  • PHP no es seguro.
  • No es escalable.
  • Java tiene frameworks que facilitan el desarrollo de aplicaciones.
  • Java es más fácil.
  • Java lo usan más empresas.

Como vemos existen muchos prejuicios (recalcando la palabra prejuicio) alrededor de los marcos tecnológicos basados en PHP, muchos de ellos totalmente falsos y otros muchos demasiado poco matizados como para poder tomarlos en consideración. Porque las facilidades que PHP o cualquiera de sus frameworks (Symfony, Cake, etc) o productos (Magento, OSCommerce, Drupal, Phing, Xinc, etc) proporcionen para gestionar la seguridad y la escalabilidad, la capacidad de un técnico para asimilar nuevos conceptos, etc no quedan exclusivamente determinados por el marco tecnológico, al igual que las herramientas utilizadas para desarrollar un producto no determinan totalmente la calidad de éste, sino que nos proporcionan esa serie de criterios, comentados al principio, que debemos evaluar para conseguir seleccionar el marco tecnológico que mejor se ajuste a nuestras necesidades y las de nuestros clientes.

No se trata de hacer una defensa desaforada de los marcos tecnológicos basados en PHP o cualquier otra tecnología, sino de hacer una defensa de la toma de decisiones razonada y basada en criterios y motivos sólidos y fundamentados.

No existen soluciones, solo caminos que merece la pena tomar. Proverbio chino.