https://a.storyblok.com/f/270183/1368x665/cdc0a5ba8b/25apr_dev-blog_pest-architecture-testing.jpg

Controle su refactorización heredada con pruebas de arquitectura PEST

Publicado el April 29, 2025

Tiempo de lectura: 5 minutos

PEST comenzó en la imaginación de Nuno Maduro y Luke Dowling en 2021, con la misión de aparentemente traer el estilo de pruebas tipo JEST del mundo JavaScript al mundo PHP a través de Laravel. Desde entonces, ha habido dos grandes versiones del proyecto y un montón de nuevas características para levantar las cejas.

Para mí, fue la introducción de la arquitectura pruebas que no había visto antes. Claro, deberías escribir pruebas para absolutamente todo lo que haces (¡y deberías hacerlo!), pero ¿qué utilidad tendría escribir pruebas sobre la propia estructura de la aplicación? Bueno, para empezar un proyecto nuevo: probablemente no mucho. Pero aquí es donde la belleza de la misma entró en: ¿qué pasa con la introducción en un gran legado de edad plato de espaguetis que necesita refactorización gestionado? Ahora sí. En este artículo, veremos los puntos de partida más sencillos para poner en marcha una refactorización heredada con pruebas de arquitectura PEST.

Una para los directores técnicos

¿Qué puede hacer? Bueno, utilizando la función arch() podemos hacer varias cosas con la API de Expectativas PEST:

  • Definir dónde se pueden ampliar las clases y cuándo no

  • Defina dónde se sitúan sus interfaces

  • Definir qué clases deben y no deben utilizar traits

  • Refactorizar accidentalmente morir() o dump() antes de que se dispare algo como PHPStan/Psalm

  • Haga que su aplicación se adhiera a las convenciones de nomenclatura de Laravel

Eso es un montón de cosas fuera de la caja. Así que, digamos que usted hereda un nuevo proyecto, y en una hora, usted puede comenzar la refactorización con pruebas de alto nivel. Por lo tanto, el escenario ideal que querrías cuando entras en una base de código heredada sería:

  • Redactar la guía de estilo sobre el aspecto y el funcionamiento de la lógica de la nueva aplicación.

  • Empezar a escribir pruebas PEST fallidas para implementar esto.

En cierto modo, lo que me parece que se propone es una reimplementación del Desarrollo Orientado al Comportamiento. Piensa en la guía de estilo como tus pruebas tipo Gherkin, que luego traduces en pruebas unitarias y de integración en PEST.

Predicar con el ejemplo

Todo esto es académico sin ejemplos, así que vamos a tomar la teoría de que usted tiene una base de código Laravel legado. Antes de que las pruebas entren en juego, vas a querer o bien utilizar una herramienta de auto-refactorización como RectorPHP para gobernar los conjuntos de reglas de PHP que traerán el código de vuelta a las convenciones modernas, o puedes usar Laravel Shift. A partir de aquí, podemos introducir PEST usando Composer:

composer require pestphp/pest --dev --with-all-dependencies

A continuación, puede inicializar una nueva configuración PEST:

./vendor/bin/pest --init

Esto creará su Pest.php que, si estás familiarizado con el uso de PHPUnit, es el equivalente del archivo de configuración phpunit.xml. Es hora de ponerse a trabajar.

¿Y ahora qué?

An image of a big old mess of wires, just like your legacy codebaseDoes Your Code Look Like This?Aquí está. La razón por la que tienes una carrera en tecnología. Vives por heredar una aplicación Laravel de hace 15 años que tiene rutas de depuración exponiendo completamente los comandos CLI del núcleo, tienes dependencias circulares, y probablemente tienes DB::raw('SELECT * FROM pesadilla WHERE refactoring = 1'); por todas partes.

Vamos a crear una regla que cualquier comando de depuración accidentalmente comprometido en la base de código debe ir antes de que cualquier progreso se puede hacer. Eso es lo mínimo, ¿verdad? Esto está incorporado en PEST, así que primero crea una prueba en la línea de comandos usando la consola:

php artisan pest:test DebbugingRulesetTest

Ejecute el ejecutor de pruebas:

php artisan test

Observará que fallará, ya que PEST ha intentado calderizar el código. Vaya al archivo de prueba DebuggingRulesetTest.php y reemplace el código así:

<?php

arch()->preset()->php();

Haz las pruebas, y dado que has heredado un lío teórico: espero que PEST empiece a quejarse.

A screenshot of PEST failing because a clumsy developer put a var_dump() inWhoops, No Debugging Code Here, Please!

Alt:

Hemos asegurado la primera regla de refactorización, ahora necesitamos hacerla cumplir. Hay varias maneras de hacer esto; en entornos de producción, es común que un ejecutor de integraciones continuas como Bitbucket Pipelines de Atlassian, CI/CD de Gitlab, o Actions de GitHub dispare reglas para poder fusionar Pull Requests. Nosotros, sin embargo, vamos a implementar las reglas más estrictas, donde usted ni siquiera puede comprometerse con el código sin PEST ser satisfecho.

Esto se hace a través de git hooks. Crea un nuevo hook pre-commit con este comando:

cd my-code/.git/hooks

// Windows Users Only
echo. > pre-commit

// Unix-like Users Only
touch pre-commit
chmod +x pre-commit

Abrir el precommit creado en el paso anterior en un editor de texto o IDE, y añada el código para ejecutar PEST:

#!/bin/sh

echo "Pre Commit Test Runner Fired"

# Detect OS

if [ "$(uname 2>/dev/null)" = "Linux" ] || [ "$(uname 2>/dev/null)" = "Darwin" ]; then u
    echo "Running Unix-like"
    CMD="./vendor/bin/pest"
else
    echo "Running Windows"
    CMD="vendor\\bin\\pest.bat"
fi

$CMD
RESULT=$?

if [ $RESULT -ne 0 ]; then
    echo "Cannot Commit, Tests Failed"
    exit 1
fi

echo "Commit Success"

exit 0

La página pre-commit es un nombre de archivo reservado que git busca para varias acciones - en este caso, cualquiera que sea el contenido dentro de ese archivo se ejecutará cada vez que un usuario intente hacer un commit en el código base.

Adelante, intente introducir un cambio en el código y observe lo que ocurre.

Esto nos prepara muy bien para iniciar nuestra refactorización como punto de partida. Hemos cubierto la configuración, por lo que ahora es sólo cuestión de utilizar los métodos de la API de Pruebas de Arquitectura PEST. En nuestra prueba, podemos añadir un par más de reglas de alto nivel:

<?php

arch()->preset()->php(); // our previous rules
arch()->preset()->security();
arch()->preset()->strict();

He añadido un par de reglas aquí, que puedes ver en detalle en el código fuente de PEST. La primera de ellas, seguridad(), te ayudará mucho en tu refactorización inicial: se encarga de fallar tu código e identificar dónde hay serios agujeros de seguridad. Estos incluyen el uso de métodos de la Librería Estándar de PHP que han sido reemplazados por razones de seguridad, tales como

  • md5(): Los usos similares a MD5 realmente necesitan ser reemplazados por SHA256, por lo que si tienes datos como IDs de sesión o identificadores únicos de base de datos, estos necesitan tener un refactor de tipo ETL.

  • rand(): La función aleatoria original de PHP no es realmente aleatoria

  • shell_exec(): Llamar al shell de la máquina anfitriona es, posiblemente, lo peor que puedes hacer. Necesitarás hacer esto, por supuesto, en algún momento, pero la idea aquí es que utilices la consola de Laravel y los métodos envueltos para la seguridad en lugar de dejar que el código heredado destroce tu servidor.

Teniendo en cuenta el número de reglas que contienen sólo estos puntos de partida, creo que eso supone un par de sprints de refactorización. Hay todo tipo de cosas que creo que se podrían hacer con esto, dado que PEST permite toda una plétora de pruebas en la API Expectation.

Conclusión

Además de las pruebas de arquitectura, en PEST 3 también se introdujeron las pruebas de mutación. Sin embargo, la cantidad de funciones con las que viene PEST es realmente un arsenal completo de herramientas para aquellos que se encargan de proyectos heredados. En Vonage nos apasionan las pruebas, así que ¿te apetece charlar con nosotros sobre PHP? Únete a nuestra próspera comunidad de desarrolladores en Slacko síguenos en X (antes Twitter), o suscríbete a nuestro Boletín para desarrolladores. Mantente conectado, comparte tus progresos y entérate de las últimas noticias, consejos y eventos para desarrolladores.

Compartir:

https://a.storyblok.com/f/270183/400x385/12b3020c69/james-seconde.png
James SecondePromotor senior de desarrollo PHP

Actor de formación con una disertación sobre la comedia, llegué al desarrollo de PHP a través de la escena de las reuniones. Puedes encontrarme hablando y escribiendo sobre tecnología, o tocando/comprando discos raros de mi colección de vinilos.