Este es el tutorial que vamos a tener en cuenta para la charla de la WordCamp Galicia 2025.
Antes, dos conceptos:
- Test Driven Development
- Trunk Based Development Workflow
Configurar tu plugin con Unit Tests
Esta guía está basada en la realización de Tests con PHPUNIT e instalado en el propio repositorio con composer. Es la forma más fácil de que los desarrolladores puedan compartir un mismo entorno al desarrollar el plugin.
En WordPress CLI tenemos un comando para configurar nuestro plugin para instalar los archivos iniciales para realizar tests.
wp scaffold plugin-tests plugin-name --ci=github
Al ejecutar el comando, te instala los siguientes archivos:
- bin/install-wp-tests.sh → bash que instala entorno de pruebas.
- phpunit.xml.dist → configuración de PHPUnit.
- tests/bootstrap.php → carga WordPress, configuración y plugins antes de los tests. Aquí podremos poner constantes del entorno.
- tests/test-sample.php → ejemplo de test.
- .github/workflows/phpunit.yml → integración con GitHub Actions.
Necesitamos ahora PHPUNIT en nuestro repositorio. Para tenerlo en nuestro repositorio, lo instalaremos con composer:
composer require --dev yoast/phpunit-polyfills:^1.0 wp-phpunit/wp-phpunit:^6.3
Con esto instala:
- WP-PHPUNIT. Una implementación del entorno de testing de WordPress usando PHPUnit. Es un fork no oficial, mantenido por la comunidad, que hace más fácil correr tests sin tener que clonar todo el core de WordPress manualmente.
- PHPUNIT-Polyfills. Una librería creada por Yoast para proporcionar compatibilidad entre múltiples versiones de PHPUnit y diferentes versiones de PHP.
Te recomiendo que luego uses distignore para quitar archivos de desarrollo que no queremos que aparezcan en nuestro plugin final al crear el ZIP de distribución:
# PHP Unit
.github
.phpcs.xml.dist
.phpunit.result.cache
phpunit.xml.dist
phpcs.xml.dist
tests/
bin/
Y como vamos a tener el repositorio en Git, añadiremos carpetas y archivos que no queremos que aparezcan. En el archivo .gitignore añadir:
vendor/
.phpunit.result.cache
Y actualizar Composer con estos scripts para ejecutar los tests más rápido.
Añadiremos los comandos correspondientes a la ejecución de tests y a la creación del entorno para facilitarnos el trabajo.
,
"scripts": {
"test": "phpunit",
"test-debug": "XDEBUG_MODE=debug XDEBUG_TRIGGER=1 phpunit",
"test-install": "bash bin/install-wp-tests.sh wordpress_test root 'root' 127.0.0.1 latest"
}
A mi me gusta organizar las carpetas por tipos de Test.
En este caso crea las carpetas:
tests/Unit
tests/Data
Ahora ejecutamos nuestro script para instalar nuestro entorno de pruebas de WordPress para poder crear tests.
composer test-install
Se habrán creado los archivos en nuestro repositorio, pero antes de ejecutar los tests, te recomiendo estos ajustes que van a prevenir errores después.
Personalizaremos el archivo phpunit.xml.dist y en la linea directory quitar prefix=»test-» porque dependiendo de la versión, dará conflictos y errores. Además, he creado una subcarpeta para tener los tests en tests/Unit/. Puedes personalizarlo a tu gusto.
<testsuites>
<testsuite name="testing">
<directory suffix=".php">./tests/Unit/</directory>
</testsuite>
</testsuites>
Mueve el archivo test-example.php a la subcarpeta /Unit.
Finalmente, te recomendaría añadir estas líneas al principio del archivo bootstrap. Sirven para definir una constante donde vamos a encontrar los datos de entrada, y también para prevenir que no haya errores con la constante WP_CORE_DIR.
define( 'TESTS_PLUGIN_DIR', dirname( __DIR__ ) );
define( 'UNIT_TESTS_DATA_PLUGIN_DIR', TESTS_PLUGIN_DIR . '/tests/Data/' );
// Define WP_CORE_DIR if not already defined
if ( ! defined( 'WP_CORE_DIR' ) ) {
$_wp_core_dir = getenv( 'WP_CORE_DIR' );
if ( ! $_wp_core_dir ) {
$_wp_core_dir = rtrim( sys_get_temp_dir(), '/\\' ) . '/wordpress';
}
define( 'WP_CORE_DIR', $_wp_core_dir );
}
¡Por fin! Ya estamos listos para ejecutar los tests en nuestro plugin de WordPress:
composer test
Debería de aparecerte:
PHPUnit 9.6.24 by Sebastian Bergmann and contributors.
1 / 1 (100%)
Time: 00:00.005, Memory: 42.50 MB
OK (1 test, 1 assertion)
¿Qué viene a continuación?
Ya tenemos el entorno creado en nuestro plugin, y ahora toca desarrollar. Genera datos para las funciones, ejecútalo y comprueba que los resultados esperados son los correctos. Para comprobar dichos resultados puedes usar las funciones assert de PHPUNIT.
Here are the most common assert functions you’ll use in PHPUnit:
- assertTrue($condition) → Checks that a condition is true.
- assertFalse($condition) → Checks that a condition is false.
- assertEquals($expected, $actual) → Verifies that two values are equal (non-strict).
- assertSame($expected, $actual) → Verifies that two values are the same (strict: type and value).
- assertNotEquals($expected, $actual) → Verifies that two values are not equal.
- assertNotSame($expected, $actual) → Verifies that two values are not the same (strict).
- assertNull($variable) → Checks that a variable is null.
- assertNotNull($variable) → Checks that a variable is not null.
- assertEmpty($variable) → Checks that a variable is empty.
- assertNotEmpty($variable) → Checks that a variable is not empty.
- assertCount($expectedCount, $array) → Checks that an array (or countable) has the expected number of elements.
- assertContains($needle, $haystack) → Checks that a value exists within an array or string.
- assertNotContains($needle, $haystack) → Checks that a value does not exist within an array or string.
- assertInstanceOf($class, $object) → Verifies that an object is an instance of a given class.
- assertIsArray($variable), assertIsString($variable), assertIsInt($variable), etc. → Type assertions.
- assertGreaterThan($expected, $actual) → Checks that a value is greater than another.
- assertLessThan($expected, $actual) → Checks that a value is less than another.
👉 These are the most frequently used, but PHPUnit provides many more for specialized cases.
Finalmente te recomiendo ejecutar las funciones para datos de entrada correctos y también incorrectos o que le falten datos. De esta forma, haremos nuestras funciones más robustas y preparadas para diferentes datos de entrada. A ningún usuario le gusta ver Fatal error al usar su plugin.
Ejecutar tests para plugins de WooCommerce
Si necesitas ejecutar tests y tu plugin tiene dependencias, tienes que añadir la instalación del plugin en install-wp-tests.sh y además cargarlo en _manually_load_plugin .
Vamos a hacer el ejemplo si quieres añadir el plugin de WooCommerce en tus tests.
En el archivo bin/install-wp-tests.sh , antes de la linea install_wp, añade las lineas que te permiten bajar el plugin WooCommerce para las dependencias necesarias.
# Installs WooCommerce plugin in the test environment
install_woocommerce() {
local PLUGIN_DIR="$WP_CORE_DIR/wp-content/plugins"
mkdir -p "$PLUGIN_DIR"
WOOCOMMERCE_URL="https://downloads.wordpress.org/plugin/woocommerce.zip"
download "$WOOCOMMERCE_URL" "$TMPDIR/woocommerce.zip"
unzip -q "$TMPDIR/woocommerce.zip" -d "$TMPDIR/"
rm -rf "$PLUGIN_DIR/woocommerce"
mv "$TMPDIR/woocommerce" "$PLUGIN_DIR/woocommerce"
echo "WooCommerce plugin installed successfully."
}
Y después de la linea install_wp, añade el la función para que se ejecute justo después de haber instalado WordPress: install_woocommerce
Y también tendremos que incluirlo en tu bootstrap dentro de la función _manually_load_plugin:
// Load WooCommerce first from the standard WordPress plugins directory
require_once WP_CORE_DIR . '/wp-content/plugins/woocommerce/woocommerce.php';
Configurar los tests automáticos en GitHub
En el archivo de configuración que hay en .github/workflows/testing.yml, revisa la configuración y comprueba que la rama principal de tu repositorio es la correcta, sino, tendrás que actualizar el archivo yml:
on:
pull_request:
branches:
- trunk
Actualiza trunk por tu rama principal del repositorio.
Te recomiendo actualizar las lineas de setup de PHP y además, necesitarás que tenga instalado SVN que por defecto no está instalado.
- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: ${{ matrix.php-version }}
tools: phpunit-polyfills:1.1
extensions: mbstring, xml, zip, intl, pdo, mysql
coverage: none
- name: Install SVN
run: sudo apt-get update && sudo apt-get install -y subversion
Problemas comunes
Could not find /wordpress-tests-lib/includes/functions.php, have you run bin/install-wp-tests.sh ?
Aparece cuando la instalación de WordPress temporal está incompleta. Borra las carpetas y vuelve a ejecutar la instalación.
Al ejecutar la instalación del entorno de tests te indica el directorio donde está instalado WordPress. Por ejemplo yo tengo:
/var/folders/kk/6287m8gj09xdkt2zgz432zhr0000gn/T/
Habría que eliminar las carpetas wordpress-tests-lib y wordpress, y volver a ejectar la instalación.
rm -rfv /var/folders/kk/6287m8gj09xdkt2zgz432zhr0000gn/T/wordpress-tests-lib/
rm -rfv /var/folders/kk/6287m8gj09xdkt2zgz432zhr0000gn/T/wordpress/
composer test-install
Class test-sample cannot be found in /tests/Unit/test-sample.php
Si PHPUNIT es mayor que v9, el nombre del del archivo tiene que llamarse igual que la clase.
PHPUnit Version Incompatibility: The project was using PHPUnit 12.3.4, which is very new and not compatible with the WordPress testing framework. This caused additional errors when trying to run the tests.
Charla





Transcripción de la charla
Hola, hola. Bueno, vamos a continuar el siguiente taller con David, David es director técnico de la esencia de marketing y de desenvolvimento CLOSE. Ademais, forma parte do equipo de revisión de plugins de WordPress.org, así que, se tedes alguna historia con él. Vale, no sector da formación, ten experiencia técnica creando seccións de contido para programas, conectando sitios web a CCRM para asistenar clientes potenciais, equipos, publicidade, etc. Ademais, David está moi implicado na comunidade de WordPress, colaborando activamente en eventos e encontros locais. Así que, nada máis, deixo vos con David para que vos explique como facer test nosos plugins. Gracias. el resto que no veis y los que lo estáis haciendo podamos hacer test automáticos porque realmente ayuda muchísimo a la calidad del plugin y sobre todo lo que yo me he dado cuenta cuando he implementado este tipo de trabajo es que no hay regresiones o sea que realmente cuando tú ya montas los test haces tus funciones y luego esperas una entrada normalmente cuando ya hace una nueva versión o hace algún cambio no revierte o no rompe nada anterior que eso es muy importante porque muchas veces cuando hace una nueva versión resulta que puede romper cosas que a lo mejor y la gente se nos queja sobre todo si tenemos plugin comercial o plugin de comunidad esto está aquí parpadeando no sabemos por qué y a ver si damos con la tecla pero bueno os voy contando mientras vale qué son los test automatizados un tematizado es un o los test unitarios hay varios tipos de test pero nosotros vamos a tocar el test unitario el test unitario está basado en que nosotros son pruebas automáticas que hacemos nuestra función para ver si funciona o si dan un valor esperado que nosotros esperábamos y lo bueno de ustedes unitarios que aparte podemos jugar mucho a putear esa función o digamos a gastarle a gastarle porque muchas veces la vida real pues tú esperaba un número y no te viene un número tiene un string o un array típico que le falta una clave y no viene la clave toda esa perfecto no sólo voy a ahondar en la parte de dentro en una entrada perfecta como debería venir los datos sino también vamos a ir a buscarle putadillas a la función hablando mal y pronto para que se comporte bien porque nosotros lo que nos podemos dar un error fatal en nuestro plugin nuestras funciones que al final da un si una interfaz que se rompe wordpress y a lo mejor incluso podemos romper la web completa segundo de éste la función si es de admin pues en principio sería sólo la parte de mí y la parte de front no pero pero poder romper entonces es muy importante esa parte también que la vamos a ver también lo voy a ver con ejemplos vaya de funciones que son muy sencillas una suma pero y si no te viene un número te viene un texto pues eso es súper importante y sobre todo utilizando en programación negativa lo bueno es que tú en la función primero depuras lo que te va a venir de entrada devuelve una cosa u otra y a partir de ahí pues ya va arreglando y no teniendo problemas al final lo que estamos hablando es que aislamos esa función ejecutamos con una entrada de datos esperada y una salida esto es muy interesante porque por ejemplo muchas veces nos pide una función de un cliente y nos dice pero mira esta función tiene que dar este resultado y lo tiene muy fácil entonces con esto lo graban en los test unitarios grabas o sea escribes lo que tú le das de entrada lo que tú esperas de salida y entonces ya empieza a desarrollar realmente en los test unitarios se ven como que hago mi función y ahora tengo hacer los test es mucho más trabajo mucho más esto es más lento no lo hago no no si tú desde el principio ya integran los test unitarios y empiezas a escribir lo que cómo debería entrar la entrada de cómo debería entrar la salida lo que el desarrollo de la función lo vas haciendo sobre la marcha entonces ya el test ya lo tienes grabado y cuando ya termina ya te aseguras de que se está ejecutando correctamente puede darse alguna vez que la función se haya roto por cualquier cosa que nosotros no controláramos no pasa nada cogemos esa entrada nueva la grabamos como test y ya nos aseguramos que nuestra función no se va a romper más veces con ese tipo de entrada sobre todo muy importante es que no hay regresiones que al final pues en nuestro código mucho más confiable y luego pues que da mejor sensación a los clientes y a los usuarios en definitiva lo he insistido mucho por eso que previene las regresiones aumenta la fiabilidad de la confianza facilita el mantenimiento como decía si sale un nuevo error ese error lo podemos meter a añadir nuestros test y a partir de ahí ya el mantenimiento del siguiente ya va a ser la nueva versión va a tener ese arreglo a ese problema la calidad es mucho mejor de nuestro código y evidentemente cuando tenemos un código mucho más confiable, mucho más fiable, no tiene regresiones, pues va a bajar muchísimo la percepción de nuestro usuario, que al final es un poco lo que buscamos. Aquí solo vamos a tocar el test unitario, pero bueno que sepáis que hay tres, test unitario, test de integración y test funcionales, y que a partir de ahí podemos hacer. Os quiero dejar dos conceptos, no es el objetivo de esta charla, hablas de método de trabajo, pero por lo menos que os vaya sonando, es Test Drive Development, que bueno, aquí he hecho el dibujillo este que es así un poco de mal, pero básicamente se basa en que tú primero generas el código con un test, o sea, no, perdón, haces el test en el código, generas el código y vas haciendo hasta que ya se cumple todo correctamente y vas haciendo. Entonces, desde el principio, la función antes de empezar a escribirla, estás generando lo que tiene que entrar y lo que debe salir. Este, si os documentáis un poquito más, veréis que hay un montón de cosas. Y otro, también otro concepto muy interesante es Trunk Based Development. Os dejo un enlace que hice en un artículo en que se basa. Y esto es, como nosotros trabajamos normalmente con un control de versiones, bueno, ahí en el artículo os mandaré, lo veréis. La ventaja de hacer el Trunk Based Development quiere decir que tú usas una sola rama y cuando crea una nueva funcionalidad, crea una rama nueva. Hace esa rama, desarrolla, hace los test y si utiliza Gihab, los test automáticos, antes de integrarlo en la rama principal, le ejecuta un montón de test. En Plugin Check Plugin, que es un plugin que os recomiendo que hemos hecho el equipo de plugin, se ejecuta casi 800 afirmaciones, 800 y pico, con distintos entornos de PHP, con lo cual cuando tú sacas una nueva funcionalidad en el plugin te aseguras de que está muy bien, vamos que es muy consistente y no vas a tener ningún problema. Esto lo que se va a hacer es que sólo tiene una rama y hace una rama para cada desarrollo nuevo, no hace varias ramas y va complicando el código ahí os dejaré un artículo y yo para que lo profundicen en él bueno lo que nosotros al final queremos es que antes de hacer esa mergeo a la rama principal es decir que vamos a sacar una nueva versión porque se ejecuta un T automático aquí os enseña uno que da error evidentemente cuando este por ejemplo este entorno de prueba automática hace pruebas sobre el 74 el 80 el 81 y 82 y 83 lo normal es que si tiene un plugin para un cliente pues ya el entorno lo tenéis más o menos comprobado sabéis que php eso lo controláis más bien controlado entonces pues si estáis en un php 82 pues podéis vosotros subirle 83 entonces el plugin no hay problema pero cuando hacéis un plugin comercial un plugin por no controlar el entorno si es verdad que nosotros las cabeceras de los plugins podemos decirle que sea hasta una versión de php o desde una versión php y por ahí ya puedes controlar un poco más entonces le mete este unitario en distintas versiones php a las que tú das soporte que evidentemente pues tienes que empezar por lo menos de las 74 y puede darse por ejemplo a mí me pasó que un té automático fallaba en el 74 y en la 8 si funcionaba pues perfecto estoy en el momento de arreglar mi código para que no haya problema y otro concepto que bueno aquí es simplemente como referencia voy a dejar un enlace para que podáis descargar la presentación vamos a entrar ahora a móvil es cuando tú haces los test para esa salida que tú esperas vale se hace con estas funciones de web y es tú esperas un valor vale el valor esperado expecte como habéis expecte y actual y el actual es el que te da tu función de manera que tú puedes hacer tu afirmación puedes afirmar si es si es verdadero es decir si tu función devuelve un un true o un false pues tú puedes según la entrada que tú le des puedes comprobar si te va a dar un booleano que se te y en este caso un true un false si es igual a un valor eso lo vamos a ver también si yo por ejemplo vamos a hacer ejemplos sencillos y algunos enseñaré también más complejos por ejemplo yo puedo decir si yo te pongo en esta función que sume un 2 y el 4 el valor esperado tiene que ser un 6 pues hacer igual tú poner 6 ahí grabado en el código y la actual el que se ejecuta de la función bueno hay un montón más aquí os dejo unos cuantos los que más se usan así un poco pues por ejemplo va a ser count por ejemplo si tú si tú haces una función de entrada y esperas que haya o no sé cuántos elementos pues tú dices pues quiero que me digas cuántos elementos me ha devuelto por ejemplo, hacer empty, que el array que me devuelva de la función no esté vacío. Y bueno, hay un montón. Realmente, incluso ya cuando tenéis el código, metéis la IA en el código, pues te va a poner assert y ya te van incluso sugiriendo distintas funciones y afirmaciones. Hay un montón y al final usamos unas pocas. Aquí, por ejemplo, os hago un ejemplo, así para verlo, pero ahora vamos a ver en el código, de una función que se llama removeSpecialCharacter. Y yo lo que espero es que de ese valor de entrada debería devolverme valores sin… Esto tiene… Ah, mira, qué guay. De los valores estos de acento me debería devolverlo sin acento. Entonces, aquí como podéis ver, hacer equals, devuélveme esto. Entonces, yo ya me aseguro con esto que cada vez que se ejecuten los tests, mi función va a dar esta devolución. Y ahora después podemos gastarle putadilla de decirle, pues ahora no te voy a mandar, te voy a mandar números. Y si me da fatal error, ya mi función no funciona bien. Pues a lo mejor tengo que poner una verificación de si es un número o no. Pero lo importante no solo es que este es el ideal, este es el que, sí, sí, me va a dar siempre acentos, pues yo te voy a dar sin acentos, sino también tienes que buscar cosas raras, cosas que pueden pasar. Por ejemplo, yo tengo un plan, que vienen de API, por ejemplo, yo me conecto a una API y me devuelven un array, o sea, un JSON normalmente, lo convierto en array y ya de tal. Pero ese JSON, algunas veces, o viene vacío porque da una respuesta fallida, o a lo mejor me devuelve un valor que no era esperado, Pues todos esos casos normalmente te los puedes inventar aquí, ¿vale? Los puedes meter. Incluso te puedes inventar cosas que a lo mejor el array venga vacío, para ver cómo se comporta mi función. Que a lo mejor la clave que yo busco que no esté. ¿Qué pasa si no está? Por ejemplo, yo me conecto a ARP y me traigo un JSON de productos. Y yo para el producto, por ejemplo, utilizo la clave SCOOP, que es el que me va a comprobar si existe mi tienda online, por ejemplo. Ahora enseño un poco el código ese. Pues, ¿qué pasa si el producto viene sin SQ? ¿Qué va a hacer mi función? ¿Se va a romper o no se va a romper? Por eso es muy importante. Entonces, os insisto mucho, no solo en estos casos ideales, que lo das muy claro y ya te lo da de vuelta, sino buscarle. De hecho, os voy a enseñar, de donde sobre todo he sacado muchos test, hay muchísimos, el Plugin y Chef Plugin. normalmente hacemos una función de test que es testWithErrors o testWithOutErrors. O sea, WithErrors es que si yo le mando datos de entrada inválidos, ¿qué me va a hacer mi función? ¿Qué debería devolverme? Entonces es muy importante porque eso también insisto bastante. He hecho un plugin muy sencillito, que lo tenía aquí en WP Training. Esto es parte también, aparte de un tutorial que voy a hacer para el blog de WordPress, que ahí están en proceso de aprobación, quería que estuviera hoy, pero no ha podido ser. Así que, y la guía, vamos a crear los test unitarios directamente en este taller. Quiero decir que me ha costado un poco, porque es verdad que no está muy bien documentado y es un proceso bastante largo. Si seguís este tutorial, directamente os va a llegar. Entonces, vamos a empezar con nuestro entorno. ¿Se ve por aquí? ¿Lo pongo mancho? ¿Se ve bien? Vale, bueno. Esto es un editor de código, yo utilizo cursos, pero bueno, Visual Call, que queráis. Podemos coger el enlace este, ¿vale? Uy, ya he dado el gracias. Vamos a coger el enlace del repositorio y lo vamos a clonar, ¿vale? A ver si tengo clones. lo voy a poner aquí en usgalicia app public en plugin lo clono y aquí tengo yo mi plugin que le quiero hacer este unitario Como veis aquí tengo un par de funciones muy sencillitas, que aquí cada uno diréis yo lo haría así, al final hice yo aquí un replace de los datos de acento e incluso le hice una expresión regular para que me quitara símbolos raros, por ejemplo un espacio o un 9 etcétera. He hecho también una suma, una multiplicación, etcétera. Como veis directamente yo aquí asumo que esto es un entero y ahora vamos a buscarle las cosquillas a esa función para que no se me rompa y por ejemplo temas de Google y todo esto. Yo he hecho aquí el tutorial y si lo seguís pues yo creo que os va a ir muy bien porque básicamente lo que intento es ir paso a paso para que podáis instalar los plugins. Quien conozca WPKli, WPKli es WordPress a través de la línea de comandos, normalmente los entornos locales os lo podéis instalar, va directo, y yo voy a utilizar el comando WP Scaffold, que es como una serie de comandos que te permite crear algo sobre la base, y el Scaffold se llama Plugin Test, y este es el plugin Nami, vamos a poner nuestro nombre y le vamos a decir que el Continued Integration lo vamos a hacer con Gihas, esos son los tres unitarios que se ejecutan, pues venga, vamos a ejecutar nuestra consola por aquí y esto está en el entorno aquí tengo vpclean, vpclean 2.12 y mi plugin, bueno, preguntándome cosillas, si tenía alguna duda o alguna cosa. Y lo ejecuto. Muy bien, ya el primero. Error en las TBCs de la base de datos. Ah, vale, porque no la he… Ah, vale, no la tenía creada. Vale, me da error. esto que me pasa con la 8.2 en local.vp voy a cambiar el PHP ejecuto con mi comando a ver si ahora sí perfecto y ahora me crea una serie de archivos como veis me crea el workflow de github que lo vamos a tocar me crea el binario el binario lo que hace… ah bueno se me ha olvidado comentar un poco antes Para poder realizar T unitario hay dos formas, eso se me ha olvidado explicar. Para nosotros hacer los T unitario lo que se hace es que se hace en un WordPress que no tiene nada que ver con la instalación local que nosotros tenemos. Eso está buscado a posta para que no haya ningún plugin tercero porque estamos hablando de T unitario y estamos evaluando esa función. Es un WordPress que está vacío, que lo instalamos de base y la base de datos incluso la vamos borrando. La idea no es grabar ningún dato ahí y lo que hacemos es que la función de entrada y salida, los datos de entrada, los generamos nosotros manualmente. Os voy a dar varios ejemplos para que os podáis ver. Necesitamos tener PHP instalado en nuestro sistema, yo lo tengo instalado, y tener MySQL. ese es para composer me imagino conocer composer y bueno vamos a ejecutarlo con composer que es mucho más fácil también está la versión de WPM que necesitas dock e instalar en tu guardado yo también lo tengo porque para ciertos repositores me hace falta y entonces pues bueno ahí lo tengo entonces el install sh vale lo que aquí viene como esto se ejecuta bueno la vez tú puedes ejecutarlo las veces que quieras pero realmente no tenga que ser continuamente sigue una vez que se ha instalado bien salvo que no te derrota lo puede ejecutar básicamente lo que hace es que instala el wordpress desde cero entonces vamos a seguir aquí los pasos para que veáis que realmente son está muy bien descrito vale vamos con composer a traerle dependencias de desarrollador a nuestro plugin nos vamos a traer el php unit vale pero la versión de wordpress y vamos a coger también el de joas php polyfiles que básicamente lo que hace es que como php unit depende de la versión php que tú tengas pues se hizo esta repositoria para que no haya problemas en la versión de php y al final pueda ejecutarse unitario vale pues nada por instalamos y cogemos nuestro terminal y efectivamente estamos aquí en la esta y lo ejecutamos nos lo instala en desarrollo y bueno ahora sí Ah, vale, perdón, gracias. Vale, para ejecutar esos T unitarios hay varias librerías. Ahora hay una que se llama PEST, también que se conoce, y lo que hace ese entorno para poder ejecutar los T unitarios. Nosotros utilizamos PHP Unic, ¿vale? Y es el más común en WordPress. Entonces, se utilizan los T unitarios. Entonces, efectivamente, es una librería que te permite hacer las afirmaciones que hacíamos, las da la librería. ¿Vale? Sí, sí, gracias. Así que voy muy rápido, voy directamente a hacer los test y al final vamos dejando cosas. A ver, cosas de directo. Dice que da error. Vamos a ver. Si me deja… Si no me conecto a mi móvil. a lo mejor por proxy puede ser que tengamos algo… Vale, era por proxy, el proxy de la Universidad nos permite utilizar Composer. Bueno, ya está, vale, me ha instalado aquí un montón de… Lo bueno es que aquí te instala la dependencia, bueno, nosotros lo conoces que eso, que instalamos PHP Unit, vale, y las distintas versiones, la versión de WordPress Unit y la de Polyfill que estaba comentando. Os va metiendo archivos que vamos a ir viendo. Otra cosa, cuando nosotros hacemos un plugin y ya cuando hacemos entorno de desarrollo, empezamos a generar archivos que son de desarrollo. Habéis visto que el composer, generamos también el vendor, el vendor es todas las carpetas, todas las librerías que nosotros usamos. De hecho, el vendor, hay veces que tiene, depende del plugin, tiene librerías de desarrollo y algunas librerías finales que van al cliente. Que no las metes como desarrollo, las metes como finales. Entonces, ¿qué pasa? Que tenemos que meter en nuestro plugin directiva para que se guarden cosas en nuestro repositorio y otras cosas para el archivo que vamos a generar del plugin. Por eso, hay dos archivos muy interesantes que se llama gitignore y disignore que tienen políticas diferentes disignore es cuando tú quieres generar un zip de ese plugin os dejaron también una charla donde lo explico el zip limpio, sin archivos raros y sin archivos de desarrollo nuestro zip que nosotros generamos del plugin no debería tener entornos de desarrollo ni el.git ni cosas de desarrollo como phpunit, XML todo esto Es importante, y aquí lo pongo, que estos archivos no estén en nuestro zip final. Si está en nuestro repositorio, porque nosotros lo vamos a usar para desarrollar, pero no para el usuario final. Aquí, por ejemplo, veis que en el archivo this is not, que es para generar mi zip, que va a ir después a los usuarios para instalárselo, le pongo aquí la librería de desarrollo para que no me la genere. y en la de kitignore, que son los archivos que no quiero que se me suben a mi repositorio, pues meto el vendor, por ejemplo, y los resultados de caché del phpunit. Pero bueno, eso vamos a entrar. El composer, ¿qué he hecho aquí? Vamos a verlo. Se me queda esto aquí un poco chiquitillo. El composer, ¿conocéis todos composers? ¿Hay alguno que no lo conozca? si lo conocéis, ¿no? Vale, pues como veis, cuando he ejecutado este comando me ha puesto que estas librerías son de desarrollo y me ha metido el polyfill y el wp-php-unit Lo bueno de Composer es que también podemos meter comandos ya hechos porque hay veces que un comando súper largo nos permite hacer como un alias de comandos para poder ejecutarlo Entonces, aquí os pongo un par de comandos que vamos a ejecutar y que vamos a añadir yo lo explico para que no vamos a formatear el JSON aquí en los comandos es una directiva que se llama Scripts el Composer Test lo que haría es ejecutarme el PHP Unit pero le voy a meter otros dos uno que es TestDebug bueno, esto es más interno mío pero bueno, lo quiero poner aquí para que se ejecute una cosa muy interesante también en los test unitarias que tú puedes ejecutar el xdebath quien no conozca el xdebath es como que vas parando la ejecución de tu desarrollo y vas viendo las variables como se van comportando en tu función entonces es muy interesante cuando es una función más compleja que le meta el xdebath pero bueno, este es y el test instant esta es la ejecución de todo nuestro entorno de desarrollo aquí en The WordPress como veis es un comando que pone bash ejecuta el bash de installwptest aquí en este primer comando lo que dice es la base de datos el usuario la contraseña y dónde está yo ya se lo dejo a mi composer y así lo ejecuto más fácilmente porque pongo composer.test.instal y ya me hace todo ese comando no me lo tengo que recordar de hecho lo tenía guardado en un blog de notas y lo tenía que decir en contra si está el Composer Script y bueno aquí hago una recomendación más archivos que se me han instalado con este escafor se me ha instalado el phpcs que el phpcs son las normas de coding estándar y aquí lo que hace este archivo es decir a esa directiva de coding estándar qué tiene que escanear qué cosas tiene que no escanear qué reglas tiene que usar, bueno, pues aquí los tenemos, ¿vale? Por ejemplo, muy interesante, cuando me mira los prefijos, no ha gustado, me da a mí que dentro de 10 minutitos se va a ir más gente, cuando veáis código, el Value My Plugin, ¿vale? Aquí suelo poner el prefijo de la traducción, ¿vale? Entonces me ayuda también a que no se me pasen cadenas, mi plugin es multidioma pues no se me pasa en cadena. Entonces todas estas cosillas son directivas de código estándar. Bueno aquí te iba a decir alguna cosa más, el Composer que ya lo hemos visto y el PHP Unit que estas son las directivas de PHP Unit. No me preguntéis porque no sé el detalle de las distintas versiones de PHP Unit pero hay a partir de una versión, no sé cuál es, la 8, la 9 que esta directiva deja de funcionar. Y entonces lo que dije, bueno, directamente la quito y mi carpeta de test, para ser más organizada, la voy a meter dentro de una subcarpeta. Porque lo ideal es que en la subcarpeta test podáis meter más test. Por ejemplo, PHPStank, que también tengo ahí una, o test unitario, o más test, etc. o incluso agrupar los distintos test unitarios por de WooCommerce, que yo también lo hago. Quiero meter uno en Unit y otro de WooCommerce. Bueno, pues aquí voy a poner una organización que sea Unit. Y voy a moverme el test sample para que veáis cómo se me ejecuta el test. Entonces voy a decirle, no, mis test están aquí en Unit. Aquí pone que excluya ciertos archivos como este, ya me lo he cargado, no hace falta. y aquí tengo la directiva de phpunic podéis profundizar más aquí la idea es que por lo menos podéis ejecutar los tres unitarios y podéis profundizar mucho aquí por ejemplo me metes colores bueno aquí como quieras que se comporte claro la gracia de esto es que tú conforme ya coges un poquito ya de más experiencia pues vas teniendo tus propias directivas por la forma que te gusta a ti de codificar, de ejecutar los tests y todo eso. En este archivo están. Y luego hay un archivo también muy importante que es Bootstrap. Este es el PHP que se ejecuta antes de montar nuestro WordPress, porque realmente nosotros cuando ejecutamos el PHP Unit se monta el WordPress y ejecuta este PHP. Aquí lo que hace es que ya en el Stafol nos ha metido ciertas funciones, ciertos archivos y de hecho no ejecuta el plugin que estamos nosotros montando. Si es WooCommerce, ahora veremos cosas de WooCommerce, podemos aquí incluso que meta WooCommerce, que lo instale, porque si no las funciones de WooCommerce van a dar error. Total que aquí podemos meter en esta manualiz load plugin, podemos meter dependencias de plane que nosotros veamos. Ahora vamos a ver cómo lo modificamos porque claro, yo aquí decía que íbamos a quitar el prefix, pero también voy a usar este código que también tenéis aquí porque después voy a usar el wp-core-edit que muchas veces en los tres unitarios no está definido. Entonces me meto en vuestra, estas líneas. ¿Qué hago en estas líneas? Pues meto una constante para decirme dónde porque muchas veces los datos de entrada los podemos meter en el mismo código pero muchas veces a lo mejor podemos coger un json de api y lo planteamos en una subcarpeta pues yo me pongo una subcarpeta que se llama unit test data plugin y utilizo esa constante dentro de mis tests y aquí también otra constante wp core edit que me hace falta cuando vayamos a usar un woocommerce bueno no le da todavía instalar vamos a instalarlo composer test install y ahora va a ejecutar y guardado vamos a ejecutarlo y aquí está ejecutando el binario se está bajando a wordpress lo está instalando veremos que si tenemos WooCommerce se va a instalar también WooCommerce en la siguiente y me dice claro, la base de datos WordPress Test, que es la que estoy yo apuntando ya existe pero aquí no hay ningún miedo porque de hecho ahí no deberíamos guardar nada entonces me está preguntando ¿quieres que borre la base de datos? sí, sí, tírale, que me da igual de hecho este binario es importante porque luego cuando lo ejecutemos en GitHub, veréis cómo se ejecuta en Gija y ya ahora mismo debería funcionar vamos a ver si nuestro primer test unitario vale, pues ya lo hemos ejecutado como veis, tenemos aquí un OK y nos está diciendo bastante información que ha utilizado la PHP Uni la versión 9.6 que no ha llegado ni casi, y ha gastado no sé cuánto de memoria pero lo más importante es el color que es verde, el amarillo y el rojo cuando nosotros ejecutamos test que vamos ahora programar unos cuantos vamos a ver los test que son las funciones diferentes y las distintas afirmaciones un test puede tener bastantes más afirmaciones es decir cuando yo hago un código puedo ponerle varias afirmaciones vale que lo vamos a ver entonces aquí el verde es lo que decía el test driven tú vas a hacer la entrada poner la salida va ejecutando y va viendo entonces yo muchas veces una cosa también porque es más rápido esto por ejemplo si yo quiero hacer una función para un comer y lo hago si no lo hago con test tendría que entrar a la parte de usuario para ejecutar esa función luego tendría que ejecutarla que pasa porque he tardado mucho tiempo aquí directamente puedo incluso que vamos a ver también cómo se filtra porque cada vez cada vez que tiene más test puede costar un montón Entonces, puede incluso ejecutar un test que es una clase o puede ejecutar una función de esa clase, ¿vale? Para, digamos, terminar esa función. Pues venga, la primera que era testSample, que es esta, ¿vale? Se ha ejecutado correctamente, ¿vale? Como veis, pues era muy sencilla, era muy fácil de cumplir. AskertTrue, askertTrue sobre True, ¿vale? Pues no hemos hecho mucho, ¿vale? Entonces, vamos a hacer una primera función. voy a dejar los nombres, lo normal es que vayáis agrupando los tests por grupos funcionales, un poco para organizaros, incluso por grupos funcionales, por tipo de tipología, y al final tengas varios archivos. Ahora veréis que os voy a dar ejemplos de cosas que ya he hecho yo reales. Una cosa que hice era que me traía de una API un producto y tenía que crear un producto variable. Me daba un error de que el código de barra no me lo metía en una variante de ese producto. Pues hice el test, que era el JSON del producto, y quería ver que esa variación tuviera el barra código. Después arreglé mi función y efectivamente los tests me han validado. Pues venga, yo, como he dicho, tenemos unas funciones muy sencillas, multiplicación, ¿vale? Pues venga, vamos a ejecutar un T sobre multiplicar, ¿vale? Pues el más sencillo sería una entrada que sale perfecta. Yo, por ejemplo, A igual a 10, ¿vale? Y B igual a 20. Aquí ya me está sugiriendo la IA, ¿vale? Me está sugiriendo la suma que A más B sea 30. Entonces yo ejecuto mi test y perfecto, se ha ejecutado correctamente. Pero como la vida no es ideal, imaginaros, este lo dejo porque esta es la ideal. De hecho, lo normal es que podamos hacer funciones sobre, por ejemplo, aquí, por ejemplo, Tep Zoom without errors. No, without, no, coño. Without errors, ¿vale? Aquí voy a agrupar las afirmaciones cuando no hay ningún problema. cuando la entrada es limpia. Imaginaros, pues yo voy a meter también… No, ahora, esto es lo que quiero hacer después. No, ahora. Voy a poner, por ejemplo, un decimal. Imaginaros, ¿no? Yo aquí empiezo… Claro, los test muchas veces, ya también, cuando vas teniendo más experiencia, vas viendo dónde puedes darle caña a la función y dices, ¿dónde voy a ver yo aquí el conflicto? Y lo haces. Luego hay veces que te sorprende, porque ves casos que no… ¿Vale? Pues aquí hacemos otro. Aquí la propia AIA me está sugiriendo varios, con negativos, con positivos. ¿Vale? Vamos a ver qué pasa. Mira, aquí, por ejemplo, me ha dado un error. ¿Por qué, David? En la línea 23, ¿vale? Esperaba 0,3 y la suma le ha dado esto. Entonces vamos a ver aquí en la suma. Aquí algo tiene que ver. Por ejemplo, ¿ves? ¿Me dieron qué? Ah, vale, vale. Aquí quiere decir algo. Vale, pues a lo mejor aquí podría hacer un number format. Un number format. Format. Dos decimales. ¿Vale? Y si me da ya como. ¿Ok? ¿Vale? Pero esto es la vida ideal. O sea, yo te doy un 2 y un 3 y me va a dar 5. Pero, ¿qué pasa a lo normal? el usuario no pone un 2, pone un texto o pone hola, yo que sé pues vamos a ver qué pasa con nuestra función cuando hay problemas ¿vale? que esto es lo normal esta es la vida idílica, pero está aquí, vamos a ir a ver vamos a buscarle como decía putadilla a nuestra función imaginaros que yo le estoy dando un texto vamos a ver cómo se comporta mi función me lo estaba diciendo a mí, ¿vale? a ver qué pasa con mi función debería devolver un 30, ¿vale? pero no lo va a devolver porque, bueno, nada más que devuelve ah, bueno, pues aquí sí me lo ha cogido bien me ha convertido el 10 en número ¿vale? o sea que este, por lo pronto ya acabo de verificar que mi función aunque le meta un string me va a hacer la suma ¿vale? pero imaginaros que ahora no, esto no voy a hacerlo aquí me pone un texto que no tiene nada que ver con la función. Aquí a lo mejor deberíamos dar, podemos devolver un false, por ejemplo, ya podríamos inventar un poco qué nos debería dar la función si no… o imaginar un vacío, por ejemplo. Vamos a hacer primero un vacío, por si queréis. aquí me ha dado dos errores efectivamente, me está diciendo que aquí hay un entero y un string en la 49 esa es la función y en la 41 entonces, ¿qué ha pasado aquí? que esto era un vacío y me debe haber dado o aquí podemos decidir que debería darme en función, si debería dar un false, por ejemplo, y después yo ejecuto esa función y veo si es false, le muestro un error al usuario, han metido mal los datos o lo que sea, o aquí ya es decisión un poco nuestra, que queremos que se le muestre al cliente, al usuario. Mi primera decisión podría ser, por ejemplo, forzar que los números sean enteros o decimales, Entonces yo puedo decir, o pongo aquí el a, ¿ves? Flow as bar, flow as bell, y aquí lo que va a hacer es que me va a convertir. El vacío me da un cero normalmente cuando lo convierto. Entonces aquí me va a sumar, a ver, aquí 10 y 0 debería ser un 10 para que se ejecutara bien la función, ¿vale? Pues yo ejecuto y me lo he ejecutado correctamente. Entonces ya, lo pronto, tal. Vamos a buscarle más cosquillas. Vamos a buscarle que sean textos. Yo aquí, bueno, me va a dar error la función, por supuesto, ¿vale? Porque lo que ha hecho es que el texto le ha pasado a cero, ¿vale? Entonces, aquí, aquí ya os digo que depende un poco de nosotros. ¿qué queremos que nos devuelva la función si nos han dado unos datos de entrada incorrectos? Pues podemos decirle que nos dé un false, o yo, por ejemplo, con la API lo que suelo hacer es que devuelvo un array con un resultado, me queda muy poco, ¿no? Y en el resultado le digo que es ok o false, le pongo un mensaje, le doy más datos, porque al final lo que quiero es que el usuario vea por qué ha cometido el error. Pero bueno, aquí como vamos rápido, vamos a decir que, por ejemplo, si no es numérico, que devuelva un cero. O a lo mejor que devuelva un falso, por lo que sea. Vamos a decir que sea un cero. Entonces, yo aquí debería esperar, bueno, aquí me he dicho que mi test, aquí debería esperar un cero. pues efectivamente bueno el 41 aquí no habíamos quedado este vale sí claro esto era vacío era un string sino el numérico este día sea un 0 no voy a ser un 10 pues aquí directamente entonces como veis yo voy ejecutando mi función le voy buscando las cosquillas voy buscando cosas raras que pasan y quiero que me lo ejecute vamos a algo más complicadillo en estos últimos 10 minutos si no te me va diciendo preguntas por ejemplo lo que os decía en el ejemplo de una función que me ejecuta datos datos raros aquí lo voy a meter todo junto vale no es lo ideal lo suyo es que lo vaya agrupando en distintas vamos a hacer un test test_special_chart vale y bueno aquí me lo coge esto así tal cual vamos a ejecutar la vegetal efectivamente se ejecuta bien yo le metí aquí datos raros y tal más funciona bien esto sería imaginaros que ahora yo quiero buscar en las cosquillas y quiero hoy quiero ver qué pasa con mi función si yo le meto espacio, lo normal es que los quite. Voy a ponerle un espacio, voy a ponerle un guión, voy a ponerle un arroba, a ver qué es lo que me devuelve. Lo bueno también de los test es que si no se cumpliera, si yo por ejemplo digo que debería ser aquí un guión, una cosa muy interesante es que te devuelve, fijar aquí, lo he esperado, aquí te devuelve lo que debería esperar a lo que actual estoy generando. Entonces, aquí, por ejemplo, mi función lo que hace es que los espacios y los símbolos raros los quita. Con lo cual, aquí, esta es la función que yo debería recibir. Y entonces, pues aquí, ya se va cumpliendo. Entonces, así vamos creando. ¿Qué pasa? Ahora yo creo una nueva función, una nueva cosa. Hago algún cambio. Y como lo que no queremos es que si yo hago un cambio, luego se rompa otra cosa. Pues lo bueno es que como ya lo he dejado guardado en el código, cuando yo vaya a generar una nueva función no me va a romper otras cosas. Quería enseñaros algo más complicado. Por ejemplo, yo tengo algún… Porque como veis, este ejemplo ha sido muy sencillito. vale, es que no inicié la sesión no, sí ah, vale, el or se me ha faltado aquí el or aquí por ejemplo yo he hecho test un poco más puñeterillo por ejemplo, yo aquí lo que hago es que uy, que chico vale, yo por ejemplo aquí he hecho un test que según un JSON que me dé una API, vale quiero que me crea un producto entonces, bueno, aquí lo podéis ver tranquilamente, luego lo veis pero básicamente yo le mando un JSON de producto, ¿vale? y con mi función que es la que crea ese producto en el WooCommerce y me lo ejecuta yo quiero ver qué es lo que me devuelve, esto lo que hace es que devuelve un array y me devuelve el post ID que genera, como es un como es un WordPress que está vacío yo no puedo controlar el número que me devuelve aquí pero si puedo ver que no está vacío el array que me devuelve que el status es ok y que esto es un entero y aquí empiezo ya a hacer cosas, le digo pues venga tráeme el producto, mírame que sea producto simple del scoop que yo te daba mira a ver si efectivamente la función de ProductSchool es el mismo. Como veis, aquí estoy verificando que la importación del producto se ha hecho correctamente y que mi función, que es esta, la he ejecutado correctamente. Aquí, como veis, incluso miro el precio. Mi función, por ejemplo, tiene una cosa que es que si me lo traigo de la API, cuando el producto ya existe, no debería cambiarme el título de descripción porque si no entonces machaca pues entonces yo le digo cámbiame el título de descripción me lo invento y luego después de ejecutar mi función mírame que no me hayas cambiado y efectivamente no me la cambia bueno aquí hay un montón de cosas por ejemplo mira aquí tengo yo with errors le quito el scu y qué pasa mi función antes de hacer test daba fatal error vale le mandaba un jason con un sin scoom y me da fatal error para no me da error ahora lo que hace es que me devuelve una una un array con un error y un mensaje para que el usuario le diga oye que este está piquetón ha dado este producto que más da del rp o lo que sea pues tiene error y efectivamente me devuelve un cero que normalmente cuando no se queda un producto el el poseid suele ser 0 y bueno aquí podemos hacer lo que queráis os animo, hay un repositorio que está muy bien que es el de plugin check plugin plugin guija que ahí tenemos infinidad y realmente ahí si hacemos el flujo de aquí está guija aquí si hacemos el flujo de programar un check hacer los test y hasta los equipos de trabajo ya más avanzados trabajan así. No me ha dado una función si no me ha hecho el subtest. Si no, no hay. De hecho, aquí los pull requests que nosotros hacemos, voy a enseñar algunos cerrados, se han tenido que ejecutar los tests unitarios y se llegan… A ver si hay alguno mío por aquí. Como se meten los de dependados… aquí hay uno mío, yo hice, no, pero este no lo terminé, este está, veis este por ejemplo no tiene los test, aquí está uno, aquí hice yo un check, ¿vale? y en mi desarrollo yo hacía el check, aquí hacía el desarrollo que era este check y luego le metí a los test unitarios y así, y como veis, de cara al desarrollo, pues más fácil saber que cuando tú lo ejecutas, O sea, cuando se ejecutan los checks, en este repositorio se ejecutan 27 checks, que están incluso el estilo de código, los tres unitarios, y los tres unitarios se ejecutan en distintas versiones de PHP, 7.4, 8.8.0, 8.1.2, 8.4, y 8.4 incluso en experimental. ya estamos incluso haciendo check para el PHP 8.4 para cuando este plugin salga ya tener eso previsto. Y al final lo que quiero decir es que cuando tú vas a hacer ese desarrollo, bueno aquí hay una discusión de cómo debía ser y tal, ah bueno es que esto lo oculta una vez que está terminado. Perdón, que me voy muy rápido. Cada vez que tú haces un cómic en ese QR, si seguís la guía, podría hacerlo también en Guija. Nos aseguramos que se ejecuten esos tests automáticamente, porque aquí lo hemos ejecutado nosotros local. Pero cuando lo integras con Guija, esos tests se hacen directamente también en Guija. Con lo cual, tú antes de tu nuevo desarrollo incorporarlo a la versión principal, también te aseguras de que se hace el test automático. y aquí se hacen como 900 una barbaridad no es lo mismo que yo haga un código en definitiva, que es lo que yo quería al final que viéramos un código que se ha ejecutado pues se ha ejecutado 900 test como va a ser lo mismo a que yo directamente me queda todavía 5 minutillos, puedo aprovechar todavía a ver, mejor ¿tenéis alguna pregunta? ¿váis a poner a CST a partir de ahora o no? Como tengo estos 5 minutos voy a decir por ejemplo una dependencia. Si tengo un plugin para hacer WooCommerce, aquí os dejo cómo ejecutar text para plugin de WooCommerce. Claro, yo al traerme el WordPress tengo que instalar esas dependencias. Aquí os dejo el código que es dentro para incorporar el bash para que se baje el WooCommerce y luego claro en el bootstrap que es el PHP que se ejecutaba antes de que empezara nuestro WordPress tengo que decirle que incorpore WooCommerce porque si no cuando yo vaya a hacer test y meta cuando llegue a test de WooCommerce de estas funciones la función vcgetproduct me daría fatal error pues vamos a hacerlo si yo creo que me da tiempo muy fácil nos metemos aquí al binario y aquí antes de ejecutar las distintas funciones le meto el install wwocommerce que lo voy a ejecutar después del wordpress ahí ya tendría instalado WooCommerce en mi test que lo voy a ejecutar pero necesito que esté activo entonces en el en el bootstrap aquí en manually load plugins aquí meto mi WooCommerce antes de que se ejecute mi función entonces con estos dos ajustes ya tengo WooCommerce pero tengo que instalarlo entonces composes test install vale me va a machacar el wordpress me da igual no pasa nada se me va a bajar wu comer y me va a decir si quiero borrar base datos sí sin problema ya tengo wu comer y ya podría incluso ejecutar cosas de wu comer por ejemplo bueno es que estas funciones aquí son un poco genéricas porque tienen que tener un Product ID. Aquí debería, para ejecutar esta función, en mi función TestPublic, tres minutillos, ya voy a dar el cierre. Claro, para dar yo mi función, debería crear yo antes un producto, que lo puedes hacer a través de distintas funciones. Entonces yo podría darle Product, VsGueProduct, no. Al final, para que yo pueda ejecutar mi afirmación sobre este plugin, que va a necesitar un Product Get ID. Antes tengo que crear el producto porque no existe. Lo creo y con esa creación de ese producto ya puedo hacerle test a lo que me ha devuelto WooCommerce. Entonces, ahí directamente puedo saber un poco. En definitiva, esto es un principio para que vosotros podáis ejecutar test. que realmente os animo y para que empecemos a cambiar el chip desde empezar la función a empezar a programarla primero hagamos los test de entrada los datos de entrada empecemos a ejecutar los datos de salida y ir programando nuestra función hasta que el test se haga completamente de manera que cuando ya vaya a hacer yo más cosas eso ya como que me olvido ya de definitiva nada, pues agradeceros por escucharme y espero que lo pongáis en práctica desde hoy ya de verdad que a mí me ha cambiado bastante el desarrollo porque digamos que te preocupa de problemas que tú a lo mejor te has encontrado y que no te vas a encontrar después evidentemente puede los datos de entrada pueden cambiar pero tú lo puedes ir actualizándolo en tu test muchas gracias yo como ha dicho jesús pues soy cteo de la agencia cloud y en mi tiempo libre pues soy team red del plugin temps o sea que si habéis mandado algún algún plugin al repositorio de WordPress, al director de WordPress, seguramente lo habréis revisado. Así que muchas gracias a todos. No habéis ninguna pregunta, ¿eh? No tenéis… Ah, mira, hay un par de ellas. Rápido. Rapidillo. Venga, que nos da tiempo, un minuto. Rápido. Yo me metí en programar plugins por un horror de LearnDash y funcionalidades que quería manuales. Si no, no acababa ahí ni de broma. Todo esto es para plugins que vas a subir a WordPress y compartir con otras personas. No, no, para un plugin tuyo propio incluso. Y no es demasiado, porque veo que estás haciendo todas las cosas, por ejemplo, de WooCommerce manuales sin frontend, o sea, las haces tú. Sí, sí, directamente. Entonces tienes que conocer muchísimo el entorno con el que trabajas y replicar todos los comportamientos de todos los tests que yo haría con clics. Sí. Bueno, es que ese es el test de integración. Ese es un test añadido. Esto es cuando una función que hace un proceso tú quieres hacer test automatizados para esa función el test que tú dices tú de integración se llama un test avanzado que es más de integración pero que básicamente tú al final, los test unitarios cuando tú tienes muchas funciones al final tienes que ejecutar juntas entonces hay también test para ejecutar esas funciones completas que tampoco quería entrar mucho pero que hay otro tipo de test también recomendado test de integración Me ha parecido súper interesante, la verdad. Bueno, yo me voy un poco más atrás. Yo no suelo hacer mucho desarrollo, pero estoy empezando ahí a pelearme un poquito con algunas cosas, también por proyectos propios y por luego por cosas que a veces encuentras en cliente y que acabas teniendo que meter mano. Y yo me voy más atrás, has dicho, ¿quién conoce Composer? Y digo, ahí yo ya me he perdido. O sea, entiendo de test porque he trabajado en desarrollo y sé de qué va la vaina porque tengo compañeros testers, pero ahí me pierdo. ¿Cómo empezaría alguien que quiere empezar a desarrollar y empezar a meterse en todo esto? Que no sea estar en el notepad. Sí, sí, sí. Bueno, Composer PHP, Composer es una forma de instalar, aquí sale como un director de orquesta, básicamente es un archivo que tú guardas en tu plugin, un poco así resumido, donde te pone todas las dependencias de tu plugin. Entonces, cuando ya empiezas a hacer plugins más avanzados y que tienen muchas más funcionalidades, tienes dependencias. Y la gracia de la dependencia también es que las puedes ir actualizando. Mucho más fácilmente que si tú te bajaras la librería y la incorporaras en un subdirectorio de tu plugin. La mejor forma de hacerlo es con Composer. Te lo tienes que instalar en tu ordenador porque al final lo ejecutas en comando. Y bueno, ahí librería lo que tú quieras. Incluso tú puedes crear propias librerías. Y el entorno ese que estabas utilizando, ¿qué es? ¿Cuál qué entorno? Porque ahí yo ya… Ah, sí, el cursor. Yo usaba cursor. Esto. Sí, pero esto es cursor. Porque eso he visto, de que te ha empezado ya a recomendar todo la IA directamente, te sacaba las propuestas de tal. Esto es una maravilla. Bueno, pues tienes Visual Code o con Guiz Casco Pailo, que tiene una versión gratuita, que para empezar está muy bien, y te va autosuscribiendo. Como ves, me va suscribiendo, me tengo que… Al final, los desarrolladores que estamos implementando la IA, en nuestro desarrollo, pues lo que hacemos es pelearnos con la IA, básicamente. Porque tú, incluso con el chat, que aquí no he usado yo el chat porque tampoco era… Aquí le puedes decir, pues házme los test, porque claro, yo quería que conociera el concepto, pero tú le puedes decir, házme los test unitarios para este plugin. Y te lo puede hacer. Y te los crea, te crea los archivos y todo eso. Pero GitHub Copilot, has dicho que es como este extra de IA que le puedes poner. Sí, justo. Y en curso va ya incorporado. Bueno, esto es los ID. ¿Qué? Es que no… Sí, te digo, está Cursor. Eso. Bueno, está Winsure. Bueno, aquí. Ya verás, en el Cafelillo, pues, algunos serán de un… Este es el mejor ID. No, tú no, que estás usando Visual Code, no tienes ni idea. Total, hay también un poco de enfrentamiento en el ID. ¿No? Hay algunos que son de PHP Store. Pero, bueno, básicamente Visual Code. A mí me gusta, yo, del editor, nos vamos allá. del editor que teníamos antes, que era un notepad, a Visual Code fue un cambio muy gordo porque teníamos el Git incorporado y la terminal. Como habéis visto, yo he podido juntar, me he podido clonar, eso fue un cambio totalmente. Y ya Visual Code, como es OpenCódigo Abierto, han sacado ramificaciones. Cursor es igual que Visual Code, o sea que si sabes manejar Visual Code, puedes manejar Cursor. Y al final lo que hace es que te incorpora la AIA en tu desarrollo. Y te va sugiriendo. Pero al final es un trabajo de pelearte. Porque te empiezas a sugerir cosas. Esto no tiene nada que ver. ¿De qué punto de vista de productividad hay alguna diferencia grande entre el gusto y el gusto? Es gusto. Es gusto. A mí me gusta más curso porque está más actualizado. Los agentes los meten antes. Y cuando sale Cloud, por ejemplo, ha salido la 4, pues la meten y la incorporan antes. Bueno, el Visual Code también es muy avanzado. Está muy bien. Es gusto, ya te digo. También está Winsur. está trade esto ya es como peleas de desarrolladores fricadas así que nada pues nada, muchas gracias y cualquier cosilla me tenéis en la web, echadle un vistacillo a la web de David Pérez Garca os meto cosillas de os meto cosillas y ahí tenéis la charla de hoy la tenéis aquí ¿vale? directamente y ahí seguir los pasos y ustedes tienen que dar el test directamente pues nada, pues muchas gracias