Test Unitarios Con PHPUnit

Test funcionales con PHPUnit

Llevo ya un buen tiempo sin escribir, si no recuerdo mal mi última entrada fue del mes pasado y es verdad que los últimos posts se han centrado más en temas de SEO, poquito a poco he ido olvidándome del tema del que se iba a centrar el blog en un principio, desarrollo, que para eso soy desarrollador…

En los últimos 6 meses de mi vida me he visto centrado en un mega proyecto en el que se han pasado las buenas prácticas de programación por el beicon por eso en esta entrada quiero hablar de una metodología que me gusta especialmente y es el TDD o Test-Driven Development, para el que no lo sepa, tests a cascoporro.

¿En qué consiste el TDD?

El desarrollo guiado por pruebas se basa en que antes de ponernos a desarrollar un módulo de una aplicación, primero escribamos una serie de pruebas que por su propia naturaleza cuando las vayamos a correr por primera vez fallarán y a partir de estos primeros fallos, vayamos escribiendo y refactorizando el código necesario para hacer que los tests no fallen. Obviamente esta práctica hará que los plazos de entrega se retrasen pero esto le da una robustez al código y a la aplicación que no conseguiríamos sin tener que ir tirando del ya mítico prueba y error y arreglando los bugs que vayan saliendo hasta dejar estable la aplicación.

Dentro del TDD podemos y debemos hacer dos tipos de test diferentes, por un lado tenemos los tests unitarios y por otra parte los tests funcionales.

  • Test unitarios: se centran en probar una parte atómica de nuestra aplicación como puede ser el envío de emails del módulo mailer o la conexión con la base de datos. Normalmente suelo escribir este tipo de test en el CRUD de cada entidad. Para automatizar la ejecución de los test, podemos engancharlos con sistemas de Integración Continua como Jenkins o TravisCI
  • Test funcionales: este tipo de test añaden complejidad a las pruebas y consisten en probar módulos completos de una aplicación como el registro de un usuario o la compra a través de un ecommerce. Estos test los podemos enganchar con Selenium.

A día de hoy podemos realizar test con cualquier lenguaje de programación de los más utilizados y de hecho existen librerias como NUnit para .Net y Mono, JUnit para Java, QUnit para Javascript o de la que vamos a hablar hoy PHPUnit para PHP. Antes de entrar en el meollo tengo que aclarar que yo soy de los que si están desarrollando una webapp en la que, lógicamente, se utilizan varios lenguajes, me gusta realizar pruebas para todos los lenguajes…

Instalar PHPUnit

Tal y como nos explican en su página web.

PHPUnit is a programmer-oriented testing framework for PHP.
It is an instance of the xUnit architecture for unit testing frameworks.

Tenemos varias formas de instalar phpunit en nuestra máquina y todo dependerá del tipo de proyecto que tengamos y del alcance que queramos darle.

Descarga global

Con este método nos estamos asegurando que tendremos la librería instalada para poder utilizar en cualquier proyecto, es tan sencillo como descargárnosla y moverla a cualquier directorio de nuestro sistema.

$ wget https://phar.phpunit.de/phpunit.phar
$ chmod +x phpunit.phar
$ sudo mv phpunit.phar /usr/local/bin/phpunit
$ phpunit --version

Descarga en nuestro proyecto

Nos vamos a la raíz de nuestro proyecto y escribimos en una terminal lo siguiente.

$ wget https://phar.phpunit.de/phpunit.phar
$ php phpunit.phar --version

Descarga a través de Composer

Composer es una herramienta que la utilizamos en el desarrollo de aplicaciones web escritas con Symfony aunque no es algo exclusivo, algunos la consideran la versión hiper mejorada de PEAR. Composer es un instalador de dependencias, para el que venga del mundo Java es el Maven de PHP.

Mediante Composer podemos instalar PHPUnit de dos maneras. Si lo hacemos a través de la terminal tendremos que escribir lo siguiente:

$ composer global require "phpunit/phpunit=4.6.*"

También podemos hacerlos añadiendo la dependencia en nuestro fichero composer.json y actualizar, para ello…

{
    "require-dev": {
        "phpunit/phpunit": "4.6.*"
    }
}

Si eres un poco vaguete y no te gusta tirar de código (no sé que haces viendo este artículo sinceramente) tengo otro método que hará las delicias para el que configura sus programas de manera gráfica y es hacerlo a través de las opciones de configuración del PHPStorm.

Para ello nos tendremos que ir a Tools > Composer > Init Composer. Una vez que se haya inicializado hacemos click derecho en el proyecto y seleccionamos la opción de Composer | Add Dependency… y buscamos phpunit/phpunit.

Añadiendo la dependencia de PHPUnit a Composer

Añadiendo la dependencia de PHPUnit a Composer

Una vez que se haya instalado, podremos ver que el directorio vendor, es el que guarda las librerías que necesitará nuestro proyecto, se ha creado un directorio para PHPUnit.

Para que PHPStorm sepa que hemos instalado esta librería y podamos ejecutar los test tendremos que decírselo a través de la configuración global del proyecto, para ello nos dirigimos a Settings > PHP > PHPUnit. Hay varias formas de configurarlo pero lo más fácil es cargando el autoload de nuestras librerías.

¿Desde dónde voy a cargar phpunit?

¿Desde dónde voy a cargar phpunit?

Una vez configurado ya podemos empezar a escribir nuestros test. Esta librería tiene muchísimos métodos para probar cualquier funcionalidad que imaginemos por eso es recomendable que tengas la documentación a mano, pero para que os vaya sonando, un test sencillito se vería tal que así.

    class NotasTest extends PHPUnit_Framework_TestCase{
           public function testAssertTrue(){
                $this->assertTrue(1=1);
           }
           public function testAssertFalse(){
                $this->assertFalse(1=0);
           }
    }

Una vez que ejecutemos estos test, obtendremos algo parecido a lo siguiente.

Los tests han pasado

Los tests han pasado

Con Symfony hay un “problemilla” a la hora de probar el CRUD de nuestras entidades y es que cuando se van a ejecutar las pruebas, el framework todavía no ha cargado el Kernel de la aplicación y por ende el contenedor de servicios no contiene la referencia a Doctrine para poder operar con la base de datos, por ello, yo me he sacado de la manga una implementación de clases base e interfaces que resuelven el problema. Para que se vea con claridad pondré un ejemplo de un proyectillo mio…

Diagrama de mi solución

Diagrama de mi solución

Tal y como se puede ver en el diagrama de la clase base, se hace uso de tres funciones públicas que son necesarias para hacer que esto funciones.

  • Función setUp(): esta función se ejecuta antes de que se ejecute nuestro test, en ella se definen temas de configuración como la carga del kernel y del entity manager. Su ejecución la hace de manera automática la librería liberándonos a nosotros de cualquiera tarea salvo de implementarla y escribir en ella lo que consideremos importante.
  • Función tearDown(): se ejecuta cuando ha terminado de correr nuestro test, normalmente se utiliza para terminar tareas con la base de datos como hacer un flush o un rollback en el caso en que no trabajemos en una base de datos de test.
  • Función getContainer(): como su nombre indica nos devuelve el contenedor de servicios, así de simple.

Voy a dejar el código de cada clase en Pastebin para que podáis pillarlo y utilizar mi implementación en vuestros test pero a cambio os pido que le deis un +1 en Google, un Me gusta en Feisbú o lo compartáis a través de twittah para que así llegue a más personas 😉

¡Hasta que volvamos a olernos!

Gorka Muñoz Andrés

Me llamo Gorka Muñoz y soy un desarrollador melómano. Combino a la perfección la búsqueda de nuevos grupos con la pasión por la tecnología. Desde chiquitito me ha gustado la programación, ahora que soy mayor estoy metido en el mundo del SEO sin olvidarme del /Dev.

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *