Saltar al contenido

Etiqueta: phpunit

JS Archive List 6.2.0: actualización de seguridad, limpieza de i18n y más pruebas automatizadas

Hay actualizaciones “cosméticas” y otras de urgencia, con un enfoque en la calidad, porque resuelven problemas que surgen en producción. La versión 6.2.0 de JS Archive List se clasifica en la segunda categoría.

En la sección de changelog de WordPress, el foco está clarísimo: es una actualización de seguridad y viene acompañada de mejoras que, aunque no se vean en el frontend, hacen que el plugin sea más sólido a largo plazo.

JS Archive List de nuevo con una vulnerabilidad

El cambio importante: fix de seguridad en filtros por shortcode

El punto más relevante de esta versión de JS Archive List es que se corrigió una deserialización insegura relacionada con los filtros de categorías del shortcode, pasando a un enfoque de parsing seguro de IDs serializados y rechazando cualquier otro valor, como, por ejemplo, un objeto.

Es decir, si tu sitio usa shortcodes y filtros de categorías, ahora el plugin es mucho más estricto con lo que acepta como entrada. Esto reduce superficies de ataque clásicas en las que “datos con forma rara” terminan ejecutando acciones que nunca debieron ejecutarse.

No es el tipo de cambio que “se nota”, pero es exactamente el tipo de cambio que vale oro.

i18n sin sorpresas: text domain alineado con el slug

Otro detalle que descubrí sin querer es que WordPress espera que el dominio del texto coincida con el slug del plugin. En esta versión se arregló mediante cambios en los archivos de PHP, JS y de traducción.

Esto suele arreglar los típicos “¿por qué esto no se traduce si tengo el .mo?” o las inconsistencias que surgen cuando WordPress intenta cargar el dominio correcto.

Readme de JS Archive List mas claro

También se actualizaron los headers del plugin/readme (requisitos, licencia y license URI), pues ahora son requeridos y durante esta década no los había incluido. Así, el plugin tiene una mejor calidad y cumple con los lineamientos de los plugins que exige WordPress.

Más fácil brindar calidad: docs y setup de PHPUnit

Este es mi lado de profesor universitario hablando: si quieres que un proyecto sea sostenible, haz que sea fácil de probar. La nueva versión 6.2.0 incluye: documentación y script instalador para configurar la suite de pruebas con WordPress y PHPUnit

Esto reduce muchísimo la fricción al añadir pruebas, correrlas en CI y detectar regresiones antes de que algo llegue a producción. Probablemente agregue más pruebas en futuras versiones de JS Archive List.

Codex me ahorró horas

Aquí va mi confesión nerd: parte de esta actualización se benefició mucho de Codex para acelerar el trabajo “invisible”: revisar cambios repetitivos, mantener la consistencia con los estándares de WordPress y, sobre todo, acelerar la incorporación de chequeos de calidad (tests, estructura, convenciones) sin convertirlo en una semana entera de trabajo.

Eso sí, no reemplaza el criterio (eso no se delega), pero sí recorta brutalmente el tiempo entre “tengo que hacerlo” y “listo, quedó fino y revisado”.

Prueba JS Archive List y dime qué tal

Si todavía no lo has probado, este plugin existe para lo mismo que yo quería hace años: un archivo colapsable, limpio y configurable, y hoy, además, con soporte moderno vía el block de Gutenberg.

Pásate por la página del plugin, instálalo, juega con las opciones y, si te sirve, deja una reseña, reporta bugs o sugiere mejoras.

Eso es lo que mantiene vivo el software libre.

Deja un comentario

Class already exists en PHPUnit

Esta semana en el trabajo me topé con un error de Class already exists en PHPUnit. El cual me sorprendió porque no tenía mucho sentido:

Mockery\Exception\RuntimeException: Could not load mock class MiClase: class already exists

Entonces lo primero que pensé fue: “¡¿Cómo que ya existe si lo acabo de crear?!”. En mi trabajo estábamos creando una serie de pruebas unitarias (como siempre me ha gustado) para una nueva funcionalidad bastante grande, y usamos Mockery como herramienta para simular el comportamiento de clases y objetos. Si no lo conoces, Mockery es una librería para PHP que permite crear mocks, stubs y spies para probar clases de forma aislada, sin tener que depender de la implementación real.

¿Qué es un mock?

Tal vez te preguntes, ¿qué es eso de un mock? Bueno, imagina que tienes una clase llamadaServicioFactura que depende de ServicioCorreo para enviar correos. Pues resulta que cuando haces pruebas unitarias, no quieres que se envíen correos reales (que ningún usuario, inclusive el que está probando, reciba 30 notificaciones de prueba), tanto por costo, como por rendimiento y porque no se esta probando los correos. Entonces usas un mock de CorreoService que simula su comportamiento: no manda correos, pero finge que sí, y hasta puedes verificar si fue llamado o no. Bien útil. De esta forma, cuando se ejecuta la prueba, se ejecutará el mock e intercepta las llamadas y simula el comportamiento original.

Cómo solucionar: Class already exists en PHPUnit

Volviendo al error de Class already exists en PHPUnit, en el fondo, lo que pasaba es que tenia un conflicto con la instancia de un mock ya definido, es decir, habia definido un mock de una instancia de esa clase y aparte otro para la clase. . Si te estás preguntando qué es un mock de una instancia, son algo como esto:

$mock = mock('overload:' . MI_CLASE_MOCKEADA::class);

Cuando mezclas un instance mock con un mock normal, lo que en realidad estás haciendo es intentar redefinir la misma clase dos veces. Y eso ocasiona el error mencionado.

La solución a largo plazo es refactorizar ese código viejo para que nuestros tests no dependan de instance mocks. Pero la solución rápida y sencilla, es ejecutar cualquier prueba que use un instance mock en un proceso separado. PHPUnit hace esto muy fácil con una simple anotación:

/**
 * @runInSeparateProcess
 * @preserveGlobalState disabled
 */
public function pruebaQueIncluyeLosMockupsDeInstancia(): void
{
    // código con los mocks de instancia
}

Ya con eso deberías poder ejecutar la prueba, si necesitas mas información puedes ver la documentación oficial de PHP.Unit. Y si sigues con el problema, puedes probar con cerrar los mocks después de cada test con:

protected function tearDown(): void
{
    Mockery::close();
}

Palabras finales

¿Te ha pasado algo parecido? ¿Tienes otra solución o teoría? ¡Déjamelo en los comentarios, me encantaría leerte!

Gracias por leer hasta el final. Si te encontraste con el error Class already exists en PHPUnit y llegaste hasta aquí buscando respuestas, espero que esto haya sido útil.

Happy Testing! 🧪✨

Deja un comentario

Cómo crear pruebas unitarias y funcionales con Yii 1.x usando Composer

Si tienes configurado tu proyecto hecho en Yii 1.x para cargar las clases mediante composer y deseas realizar pruebas automatizadas, notarás que existen ciertas incompatibilidades entre Yii 1.x y el PHPUnit del repositorio de composer. A continuación te explicaré como instalarlo.

Instalación de las dependencias

Lo primero es instalar todos los paquetes necesarios para realizar las pruebas, todas se colocarán en la sección require-dev debido a que solo serán utilizadas durante el desarrollo y no en el servidor de producción para evitar bugs/exploits, ocupar espacio, rendimiento, etc. El paquete requerido por Yii es PHPUnit, pero al momento de desarrollo del framework, PHPUnit incluía varias funcionalidades que actualmente están disponibles en otros paquetes, por esta razón también debemos agregar php-invoker, phpunit-story y phpunit-runner. Ahora, si deseas utilizar fixtures (datos de prueba) o vas a realizar pruebas con base de datos debes agregar dbunit como dependencia, si vas a realizar pruebas funcionales agrega phpunit-selenium y finalmente, si utilizas un generador de pruebas (Netbeans incluye uno) agrega phpunit-skeleton-generator para con un clic generar un archivo de con los métodos de una clase para escribir pruebas.

Entonces la sección de require-dev en tu composer.lock debe quedar así:

"require-dev": {
	"phpunit/phpunit": "4.7.*",
	"phpunit/php-invoker": "*",
	"phpunit/phpunit-story": "*",
	"phpunit/dbunit": ">=1.2",
	"phpunit/phpunit-selenium": ">=1.2",
	"phpunit/phpunit-skeleton-generator": "*",
	"hot/phpunit-runner": "dev-master"
}

Luego ejecuta composer install y tendrás las dependencias en tu proyecto.

Configuración en Netbeans

Primero se debe configurar el proyecto para indicar cuales son las carpetas con los archivos y la configuración de phpunit a utilizar, para ello, haz clic derecho en el proyecto. En la parte izquierda entra a la sección de Testing, luego en la ventana de diálogo selecciona PhpUnit y en la selección de la carpeta, escoge /protected/tests/ para indicar que esa es la carpeta de pruebas del proyecto. Finalmente, en la parte inferior se debe seleccionar PHPUnit en la sección de Testing Providers

Selección de PHPunit en Netbeans
Selección de PHPunit en Netbeans

A continuación, en el panel izquierdo haz clic en PHPUnit, y en el panel derecho:

  • Selecciona la opción Use Bootstrap y selecciona la ruta /protected/tests/bootstrap.php
  • Activa la opción de Use Bootstrap for creating new tests
  • Selecciona la opción Use XML Configuration y selecciona la ruta /protected/tests/phpunit.xml
  • Use Custom PHPUnit Script y coloca la ruta /protected/external/phpunit/phpunit/phpunit

De esta forma le indicamos a Netbeans el uso de la configuración de arranque incluída en Yii y que utilice el script de PHPUnit que instalamos con composer.

Selección del PHPUnit de composer

Ahora necesitamos indicarle a Netbeans que utilice la plataforma de PHPUnit instalada con composer, de lo contrario puede utilizar la que viene incluida en el IDE o la del sistema operativo opertivo, las cuales son incompatibles con las clases incluidas en composer. Para cambiarlo, haz clic al menú Tools y luego Options, entra a la sección de PHP, selecciona la pestaña de Framework & Tools, luego en el panel izquierdo selecciona PHPUnit, y selecciona/escribe las siguientes rutas:

  • En la ruta de PHPUnit Scripts, coloca la ruta de phpunit de composer: /protected/external/phpunit/phpunit/phpunit
  • En la ruta de Skeleton Generator Script, /protected/external/phpunit/phpunit-skeleton-generator/phpunit-skelgen
Selección de scripts de PHPunit de Composer en Netbeans
Selección de scripts de PHPunit de Composer en Netbeans

Ejecución

¡Listo! Ya puedes ejecutar las pruebas desde la clase principal con F6 o desde la clase de pruebas con Alt + F6. Ademas, al hacer clic derecho en una clase, puedes entrar al menú de Tests y luego Create Tests para crear automáticamente los archivos pruebas, estos ya vienen con los métodos que debes escribir y métodos para ejecutar métodos antes de las pruebas.

Ahora no tienes excusa para probar tu software de forma automática utilizando Yii.

Deja un comentario