Mejora la calidad de tu código con Git y los tests automáticos
Los programadores profesionales utilizan herramientas como Git
para gestionar
el código de sus aplicaciones y herramientas como PHPUnit
para asegurar su
calidad. Los mejores profesionales van un paso más allá y nunca suben al
repositorio ningún código que previamente no haya pasado todos los tests de la
aplicación. Este artículo explica cómo automatizar este proceso.
En primer lugar, asegúrate de tener Git instalado y bien configurado. Para ello,
puedes utilizar nuestra guía de instalación de Git. Después, assegúrate de que al ejecutar el comando phpunit -c app
no se
producen errores. Este comando ejecuta todos los tests unitarios y funcionales
de tu aplicación Symfony2.
Personalizando Git con scripts propios
Git permite ejecutar tus propios scripts cuando se producen eventos importantes, un mecanismo similar al de otros sistemas de control de versiones. Estos scripts se llaman hooks y se pueden ejecutar tanto en la parte del cliente (el programador que envía cambios al repositorio) como en en la parte del servidor (el servidor que actualiza su código desde el repositorio).
Los hooks se definen en el directorio .git/hooks/
de tu proyecto. Dentro de
ese directorio verás varios hooks de prueba creados por Git y que te pueden
servir para aprender cómo crear hooks avanzados.
En nuestro caso necesitamos que se ejecuten todos los tests de la aplicación antes
de subir el código al repositorio. Por tanto, necesitamos crear un hook de tipo
pre-commit
. Crea el archivo .git/hooks/pre-commit
y copia en su interior el
siguiente contenido (que está adaptado del que puedes ver aquí):
#!/usr/bin/php <?php printf("%s > pre-commit > ejecutando los tests ... %1\$s", PHP_EOL); $proyecto = basename(getcwd()); exec('phpunit -c app/', $output, $returnCode); if ($returnCode !== 0) { $minimalTestSummary = array_pop($output); printf(" [ERROR] Algún test de %s ha producido un error: ", $proyecto); printf("( %s ) %s%2\$s", $minimalTestSummary, PHP_EOL); return false; } printf(" [OK] Los tests de %s han pasado correctamente.%s%2\$s", $proyecto, PHP_EOL); return true;
¡Ya está! Haz cualquier cambio en cualquier archivo del proyecto y trata de
subirlo al repositorio con el comando git commit
. Verás que ahora se ejecutan
los tests antes de subir el código:
$ git commit -a > pre-commit > ejecutando los tests ... [OK] Los tests de symfony.es han pasado correctamente. [master ...] ... 1 file changed, 7 insertions(+), 2 deletions(-)
Acelerando la ejecución de los tests
Cuando tu aplicación contenga muchos tests, este proceso puede ser tan lento que
te desespere subir código al repositorio. Para solucionarlo, puedes añadir la
opción --no-verify
para evitar que Git ejecute los hooks:
$ git commit -a --no-verify
Esta solución es válida cuando el código que subes al repositorio no es crítico o contiene modificaciones muy menores. Otra solución mejor consiste en dividir los tests de tu aplicación en grupos.
PHPUnit permite añadir la anotación @group
en cada test para agrupar los
tests por funcionalidades. De esta forma, podrías crear un grupo llamado
@rendimiento
para los tests que aseguran que tu aplicación es rápida, otro
grupo llamado @no_importante
para los tests no esenciales de tu aplicación, etc.
class MiTest extends \PHPUnit_Framework_TestCase { /** * @group rendimiento */ public function testPrimero() { ... } /** * @group no_importante * @group error_56332 */ public function testSegundo() { ... } }
Después, PHPUnit te permite ejecutar solamente los tests que pertenecen a un
grupo con la opción --group
:
$ phpunit -c app --group=rendimiento
Además, también puedes ejecutar todos los tests salvo los que pertenezcan a los
grupos que indiques en la opción --exclude-group
:
$ phpunit -c app --exclude-group=no_importante
Siguiendo esta idea, puedes agrupar en @importante
todos los tests esenciales
de tu aplicación y hacer que solamente se ejecuten esos al subir código al
repositorio. Para ello, modifica el código del hook anterior por lo siguiente:
#!/usr/bin/php <?php printf("%s > pre-commit > ejecutando los tests ... %1\$s", PHP_EOL); $proyecto = basename(getcwd()); exec('phpunit -c app/ --group=importante', $output, $returnCode); if ($returnCode !== 0) { $minimalTestSummary = array_pop($output); printf(" [ERROR] Algún test de %s ha producido un error: ", $proyecto); printf("( %s ) %s%2\$s", $minimalTestSummary, PHP_EOL); return false; } printf(" [OK] Los tests de %s han pasado correctamente.%s%2\$s", $proyecto, PHP_EOL); return true;
Recursos útiles
- Documentación oficial de Git sobre hooks
- Explicación de la anotación @group en la documentación oficial de PHPUnit.
¿Has visto algún error?
Avísanos en [email protected] para que podamos corregirlo. Gracias.
Proyectos Symfony destacados
La plataforma de eCommerce 100% Symfony que rivaliza con Magento y PrestaShop. Ver más
Síguenos en @symfony_es para acceder a las últimas noticias.