Haciendo TDD en PHP con Silex y PhpUnit (Parte 1)

Hace ya bastante tiempo que en el blog estamos hablando sobre PhpUnit, TDD e incluso hemos nombrado a Silex, creo que ya va siendo hora de crear un pequeño proyecto en el que aplicar todo esto. Llevo ya unos días trabajando sobre mi cuenta de github (https://github.com/jeslopcru) en un pequeño proyecto PHP donde utilizo Silex, PHP y TDD. Es solo una pequeña prueba de concepto para ver que es posible hacer TDD utilizando Silex y por tanto también podría ser posible hacer TDD utilizando Symfony2.

En este proyecto montaremos todo el entorno utilizando Composer junto PhpUnit y symfony/browser-kit (para poder hacer tests funcionales a los controladores symfony). También utilizaremos monolog para los logs. Así que vamos manos a la obra.

Información acerca del proyecto

Vamos a crear una calculadora con la que podremos hacer operaciones básicas, para utilizarla haremos uso del navegador, es decir, como URL utilizaremos algo así http://www.example.com/add?numberA=2&numberB=3 y la respuesta será la suma de ambos parámetros.
Si, es cierto, en un primer momento no parece un gran proyecto, pero lo importante de esto es que construiremos todo esto utilizando el microframework Silex y trabajando mediante TDD.

Creando el proyecto

Para crear el proyecto lo más cómodo es utilizar una herramienta como virtualhost.sh. Este script permite crear toda la configuración necesaria para crear un crear un site en Apache, mapear la dirección en etc/hosts y configurar el log de apache. Para instalarlo solo tenemos que abrir un terminal y escribir brew install virtualhost.sh

Una vez que lo tengamos instalado solo tenemos que crear el proyecto, nosotros vamos a crear un proyecto llamado http://testingsilex.dev

Solo tenemos que responder a una serie de preguntas y al terminar tendremos algo como esto:


Ahora solo tenemos que abrir nuestro IDE favorito, en nuestro caso vamos a utilizar PHPStorm, pero podríamos hacer TDD utilizando Eclipse, Sublime o cualquier otro editor de texto. Además ya tenemos instalado lo más importante composer 😉

 

Utilizando composer

Composer es una herramienta par la gestión de dependencias en PHP. Básicamente editamos un archivo JSON en donde tenemos declaradas las dependencias, después con los comandos composer install para la primera instalación y composer update para ir actualizando a medida que vayamos modificando el fichero JSON.

Aquí tenemos nuestro primer fichero composer.json

{
    "name": "jesuslc/testingsilex",
    "description": "testing siles",
    "minimum-stability": "dev",
    "license": "Open Source",
    "authors": [
        {
            "name": "JesusLC",
            "email": "me@example.com"
        }
    ],
    "require-dev": {
        "phpunit/phpunit": "3.7.*",
        "silex/silex" : "1.*"
    }
}

Una vez tenemos el archivo solo tenemos que hacer composer install una vez se hayan descargado todas las dependencias tendremos una carpeta vendor con todas las dependencias.

Creando la aplicación con Silex

Ahora solo tenemos que crear la aplicación para comprobar que las dependencias se han instalado correctamente 🙂 Para ello creamos una carpeta app y dentro de la misma un archivo llamado bootstrap.php

<?php

require_once(__DIR__ . '/../vendor/autoload.php');

$app = new Silex\Application;

$app
    ->match('/', function () {return 'Running';})
    ->method('GET');

return $app;

En este archivo es donde incluiremos las rutas, ahora creamos el index.php con el que haremos funcionar la aplicación

<?php

$app = require_once(__DIR__ . '/../app/bootstrap.php');

$app->run();

Finalmente tendremos algo como esto:

Ahora solo tenemos que abrir un navegador y entrar en http://testingsilex.dev para ver si todo está funcionando, además siempre podemos entrar en la carpeta log y ver que está pasando leyendo el log 😉

Añadiendo log a la aplicación

Una de las cosas más útiles a la hora de programar y de solucionar problemas es disponer de un buen log, así que lo que vamos a hacer es algo que nos servirá para aprender 2 cosas, 1 es como añadir log a un proyecto Silex y la otra es como utilizar composer para actualizar dependencias. Lo que tenemos que hacer es actualizar nuestro fichero composer.json, para dejarlo así:

{
    "name": "jesuslc/testingsilex",
    "description": "testing siles",
    "minimum-stability": "dev",
    "license": "Open Source",
    "authors": [
        {
            "name": "JesusLC",
            "email": "me@example.com"
        }
    ],
    "require-dev": {
        "phpunit/phpunit": "3.7.*",
        "symfony/browser-kit": ">=2.3,<2.4-dev"
    },
    "require": {
        "silex/silex" : "1.*",
        "monolog/monolog": ">=1.6.0"
    }
}
`

Una vez tenemos el composer.json tenemos que hacer composer update para añadir las nuevas dependencias al proyecto.

Quizás sea necesario crear un fichero llamado ‘dev.log‘ dentro de la carpeta logs y darle permisos desde un terminal así chmod 777 logs/

Ahora vamos a añadir log dentro de la aplicación, tan solo tenemos que cargar la librería Monolog y utilizarla, así que abrimos el archivo bootstrap.php y la dejamos así:

<?php

require_once(__DIR__ . '/../vendor/autoload.php');

use Silex\Provider\MonologServiceProvider;

$app = new Silex\Application;

$app->register(new MonologServiceProvider(), array(
    'monolog.logfile' => __DIR__ . '/../logs/dev.log'
));

$app
    ->match('/', function () use ($app) {
        $app['monolog']->addInfo('Logging example in the status route');

        return 'Up and running';
    })
    ->method('GET|POST');

return $app;

básicamente lo que hacemos aquí es crear un servicio MonologServiceProvider y añadir trazas de log así $app['monolog']->addInfo('Logging example in the status route');

Ahora si accedemos a http://testingsilex.dev veremos como en archivo dev.log de la carpeta logs empiezan a aparecer trazas de log como esta:

[2014-05-07 20:41:10] myapp.INFO: Matched route "GET_POST_" (parameters: "_controller": "{}", "_route": "GET_POST_") [] []
[2014-05-07 20:41:10] myapp.INFO: > GET / [] []
[2014-05-07 20:41:10] myapp.INFO: Logging example in the status route [] []
[2014-05-07 20:41:10] myapp.INFO: < 200 [] []

Ya solamente nos queda configurar PHPUnit para empezar a hacer TDD con Silex

Configurando PHPUnit

Configurar PhpUnit para que podamos ejecutar test es sencillo, solo tenemos que crear en el directorio raíz de la aplicación un archivo xml llamado phpunit.xml.dist y una carpeta llamada tests donde crearemos todos los test

El archivo XML debe contener esto:

<?xml version="1.0" encoding="UTF-8"?>

<!-- http://www.phpunit.de/manual/current/en/appendixes.configuration.html -->
<phpunit
        backupGlobals               = "false"
        backupStaticAttributes      = "false"
        colors                      = "true"
        convertErrorsToExceptions   = "true"
        convertNoticesToExceptions  = "true"
        convertWarningsToExceptions = "true"
        processIsolation            = "false"
        stopOnFailure               = "false"
        syntaxCheck                 = "false"
        bootstrap                   = "vendor/autoload.php" >

    <testsuites>
        <testsuite name="Silex Tutorial Test Suite">
            <directory>tests/</directory>
        </testsuite>
    </testsuites>

</phpunit>

Básicamente en este archivo de configuración indicamos a PHPUnit en que carpeta están los tests y donde el fichero de autoload para cargar todas las librerías del proyecto. Llegados a este punto deberemos tener el proyecto más o menos así:

Con esto tenemos configurado todo el proyecto para empezar a realizar tests y empezar a fondo con TDD en Silex.

Nuestros primeros tests

Llegados a este punto, debemos estar seguros de que todo lo que hemos hecho funciona y que esta bien configurado. La mejor manera de probarlo es hacer nuestro primeros tests.

Nuestro primer test con Phpunit solo sera un simple assertTrue, así que lo que tenemos que hacer es dentro de la carpeta tests, crear un archivo php llamado “Test.php”, este archivo contendrá lo básico para hacer correr nuestro primer test. El contenido de nuestro primer test será más o menos este:


<?php 
class Test extends PHPUnit_Framework_TestCase 
{
     public function testNothing()
     {
         $this->assertTrue(true,true);
     }
}

Para ejecutarlo, podemos utilizar PHPStorm o un Terminal. Con un terminal es tan sencillo como navegar a la carpeta del proyecto y ejecutar el comando phpunit

Ahora solo nos queda comprobar que el routing esta correcto y que podemos incluso testear el log de la aplicación. para comprobar que el routing esta funcionando correctamente mediante el uso de test unitarios.

Utilizando “symfony/browser-kit”  vamos a poder realizar test unitarios con los que testar no solo los métodos, sino también las peticiones GET, POST, … para comprobar los parámetros de las request, etc.

Así que para poder testar la aplicación lo que debemos hacer es crear otro test deserto lee la carpeta tests, llamado “BasicTest.php”, en este archivo crearemos una clase con 2 métodos, uno de ellos arrancará la aplicación (createaplication) y el otro testará que la ruta que hemos creado y su respuesta son correctas.


<?php
 namespace TutorialTest;
 use Silex\WebTestCase;
 class BasicTest extends WebTestCase
 {
     public function createApplication()
     {
         $app = require __DIR__ . '/../app/bootstrap.php';
         $app['debug'] = true;         return $app;
     }

     public function testStatusRoute()
     {
         $client = $this->createClient();
         $client->request('GET', '/');

        $this->assertTrue($client->getResponse()->isOk());
        $this->assertEquals(
            'Running with log',
            $client->getResponse()->getContent()
        );
    }
}

Ahora podemos volver a lanzar los test para comprobar que todo sigue funcionando.

 

Conclusiones

Ya lo tenemos todo montado ahora solo falta empezar a crear la funcionalidad del proyecto. Como hemos visto configurar PHPunit con Silex es bastante sencillo si utilizamos Composer y testar aplicaciones es una tarea complicada, no por el hecho de hacer test, sino por el hecho de que cuando se empieza con TDD los pasitos son muy pequeños y nos da la sensación de ser las personas más lentas del mundo escribiendo cosas (al menos a mi). Cuando hago TDD me siento lento y torpe porque existen partes del código que escribiría en un minuto, pero el tener que hacer el test antes, pensarlo, refactorizar, en resumen ir dando pasitos pequeños es algo muy duro al principio.

Ahora, bien es cierto que cuando terminas de escribir el código, lanzas los test y ves que todo esta OK, haces modificaciones del código mucho más tranquilo.

Bueno, con esto ya podemos dar nuestros primeros pasos haciendo TDD con aplicaciones Silex, ya lo tenemos todo configurado y sabemos que los tests funcionan, solo queda empezar a trabajar. En el siguiente post empezaremos a trabajar con Silex realizando los tests antes que el código.

 

Anuncios

2 comentarios en “Haciendo TDD en PHP con Silex y PhpUnit (Parte 1)

  1. Muy bien y interesante.
    Esperamos los proximos partes, es interesante ver como compruebas el controller y el view(la interfaz).

    Me gusta

Comenta la entrada

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s