Haciendo testing unitario al 100

Haciendo testing unitario al 100%. Hace unos días estuvimos hablando de como refactorizar controladores para separar responsabilidades. Ahora llega la hora de dar un paso más y testear unitariamente las clases que creamos.

La idea detrás de este post es que modifiquemos una clase ya construida y funcional, llenarla de tests y refactorizarla para que los test solo testeemos una clase y no necesiten más que phpunit, ni base de datos ni más clases de las necesarias.

Continúa leyendo “Haciendo testing unitario al 100”

¿Cómo crear un paquete/librería en PHP siguiendo PSR-4?

Ya llevamos bastante tiempo hablando sobre PHP, sobre como hacer TDD con PHP, como refactorizar clientes en PHP,… en definitiva, intentando entender todos los entresijos del lenguaje y mejorando poco a poco nuestros conocimientos.

En este pequeño artículo vamos a comprender un poco más acerca del estándar PSR-4 de como estructurar un paquete para que sea compatible y así hacer que nuestro código sea más reusable.

La estructura de directorios

La primera cosa que debemos tener en cuenta es que es necesario tener un orden (más o menos lógico) en nuestra estructura de directorios dentro de nuestro paquete de ejemplo: Gazpacho

Así que lo primero es crear un directorio llamado gazpacho, y dentro de éste, dos directorios: uno llamado src y otro llamado test.


Continúa leyendo “¿Cómo crear un paquete/librería en PHP siguiendo PSR-4?”

Refactorizando controladores: Separando responsabilidades

Una de las cosas más complicadas para los programadores es tomar consciencia sobre las como modelar situaciones y objetos del mundo real y aplicarlos al mundo de la programación. De vez en cuando, es necesario dar un paso atrás y pensar en lo que se ha estado haciendo.

Así es como al final, acabamos dándonos cuenta de que llenar un controlador de lógica es como crear un monstruo. Últimamente he leído mucho sobre refactoring y más de un post hablando sobre que llenar el controlador de código es algo malo, así que hoy vamos a ver de primera mano como solucionarlo.

Pongamos como ejemplo un controlador como este:

Continúa leyendo “Refactorizando controladores: Separando responsabilidades”

Skinny Controller: moviendo la lógica del controller

Cuando empecé a utilizar PHP, yo incluía bastante cantidad de lógica en el controller, entonces empecé a leer sobre refactoring y me topé con skinny controller fat models, el código de mis controlllers se reducía bastante y la lógica estaba en los modelos, pero lo único que hacía era mover el problema de sitio. Ahora … Continúa leyendo Skinny Controller: moviendo la lógica del controller

Skinny Controller: Servicios y Action-Domain-Responder

Hace unos días estuvimos viendo como hacer skinny controllers extrayendo toda la lógica de los controladores a servicios que pueden ser reutilizados. Después de leer el artículo original Paul M. Jones autor de “Modernizing Legacy application in PHP” escribió un post al respecto introduciendo el patrón Action-Domain-Responder. Así que hoy vamos a traducir el artículo … Continúa leyendo Skinny Controller: Servicios y Action-Domain-Responder

Refactorizando el cliente de “Cat API” – Parte 3 –

Esto es una traducción libre de Refactoring the Cat API client – Part III

En la primera y segunda parte hemos estado trabajando en separar las preocupaciones que teníamos al principio combinadas en una sola función.

Los principales “personajes” en el escenario ya han sido identificados: un httpClient y una caché, utilizadas por diferentes implentaciones de CatApi para poder testar y realizar un cliente para The Cat Api

Continúa leyendo “Refactorizando el cliente de “Cat API” – Parte 3 –”

Refactorizando el cliente de “Cat API” – Parte 2

Esto es una traducción libre de Refactoring the Cat API client – Part II

El mundo un sitio seguro

Cuando estas ejecutando test unitarios, no quieres que el resto del mundo este involucrado en tus tests. Ejecutar consultas en bases de datos reales, hacer peticiones HTPP, escribir en ficheros, nada de esto es deseable: harán que tus tests sean lentos e impredecibles. Si el servidor en el que estas haciendo tu petición está caído, o responde de manera inesperada tus test unitarios fallarán por razones equivocadas. Un test unitario solo debería fallar si tu código no hace lo que se supone que debería hacer.

Como hemos visto en el post anterior de la serie, tanto la clase CachedCatApi como RealCatApi de alguna manera dependen del mundo. La primera escribe ficheros en el sistema de ficheros, la segunda hace peticiones HTTP. Además, la creación de fichero y las peticiones HTTP son cosas de bastante bajo nivel, para lo cual las clases no utilizan las mejores herramientas disponibles. De la misma manera, un montón de casos límite no están siendo tenidos en cuenta.

Continúa leyendo “Refactorizando el cliente de “Cat API” – Parte 2″

Refactorizando el cliente de “Cat API” – Parte 1

Esta es una traducción libre de Refactoring the Cat API client – Part I

Mattias Noback tenía la idea de hacer una serie de videos sobre “Principles of Package Design book” pero finalmente en vez de videos hizo una serie de post con el material que tenía pensado presentar en los videos.

Para empezar esta es una pequeña pieza de código:

class CatApi
{
    public function getRandomImage()
    {
        if (!file_exists(__DIR__ . '/../../cache/random') 
            || time() - filemtime(__DIR__ . '/../../cache/random') > 3) {
            $responseXml = @file_get_contents(
                'http://thecatapi.com/api/images/get?format=xml&type=jpg'
            );
            if (!$responseXml) {
                // the cat API is down or something
                return 'http://cdn.my-cool-website.com/default.jpg';
            }

            $responseElement = new \SimpleXMLElement($responseXml);

            file_put_contents(
                __DIR__ . '/../../cache/random',
                (string)$responseElement->data->images[0]->image->url
            );

            return (string)$responseElement->data->images[0]->image->url;
        } else {
            return file_get_contents(__DIR__ . '/../../cache/random');
        }
    }
}

Como se puede adivinar, la función getRandomImage devuelve una URL de la imagen aleatoria (y que existe) de Cat API. Cuando llamamos a la función en dentro de una ventana de tiempo de 3 segundos, se devuelve la misma URL para que el servicio sea más rápido, así como para no abusar de Cat API.

Continúa leyendo “Refactorizando el cliente de “Cat API” – Parte 1″

testeando dependencias difíciles – Sin Mock

Hace unos días estuve “intentado” mejorar una librería para poder enviar comandos a Varnish y me encontré con unos cuantos problemillas para poder testar la librerías y así llegar a refactorizarla.

Varnish Cache

Según la wikipedia Varnish Cache es un acelerador de aplicaciones web, también conocido como caché de proxy HTTP inversa. Se instala delante de cualquier servidor HTTP y se configura para almacenar en el caché del servidor una copia del recurso solicitado. Esta ideado para aumentar el rendimiento de aplicaciones web con contenidos pesados y APIs altamente consumidas.

Básicamente lo que hace Varnish es ante una petición HTTP guardar la respuesta a esa petición y cada vez que un cliente realice la misma petición devolver el contenido guardado. Esto hace que nuestras aplicaciones multipliquen su velocidad por muchísimo, pero a la vez acarrea algunos problemas para invalidar la caché.

Motivación / el marrón

Un ejemplo básico sería un blog, si utilizamos Varnish para cachear los post ganaremos mucha en performance,pero que pasa si editamos un post ya publicado, para corregir una errata, para actualizarlo o lo que sea . Sería necesario descachear, pero no descachearlo todo, sino solo dicho post.

Una opción sencilla sería cada vez que editamos un post ejecutar el comando

Continúa leyendo “testeando dependencias difíciles – Sin Mock”

Cómo sacarle partido a Composer

Uno de los problemas a los que nos enfrentamos cada vez que estamos desarrollando un proyecto es a las dependencias con el framework, librerías y demás. Composer es un gestor de dependencias que nos ayuda a manejar todas las librerías externas, sus actualizaciones, el autoloading. En resumen, con Composer nuestra vida es más sencilla, pero como se utiliza, ¿Cómo sacarle partido a Composer?


Continúa leyendo “Cómo sacarle partido a Composer”