En cada actualización de versión
Sin pruebas, he tenido que comprobarlo todo a mano: la actualización exige semanas de trabajo y acaba aplazándose un año más.
Moodle · Ingeniería
Distingo tres niveles: pruebas unitarias de la lógica propia, pruebas de integración con Moodle y pruebas funcionales mediante la interfaz. Cubro los permisos, los datos inválidos y los fallos de sistemas externos en el nivel más barato que permita comprobar el comportamiento completo. Que una batería nunca haya fallado no demuestra que proteja: introduzco un fallo controlado y compruebo que lo detecta.
Pruebo la lógica propia con pruebas unitarias, la integración con la plataforma y los recorridos críticos a través de la interfaz. Incluyo permisos, casos de error y resultados observables, y elimino dependencias entre pruebas, fallos inestables y comprobaciones atadas a la maquetación.
Mi trayectoriaCuatro momentos en los que la ausencia de pruebas acaba costando dinero.
Sin pruebas, he tenido que comprobarlo todo a mano: la actualización exige semanas de trabajo y acaba aplazándose un año más.
Sin una red de pruebas que avise de los fallos, he visto equipos cambiar con miedo o renunciar a los cambios. Ese miedo deja funcionalidades congeladas durante años.
Sin pruebas automatizadas, dependo de una revisión manual amplia y me cuesta más repetirla después de cada cambio.
He visto reaparecer un fallo ocho meses después de corregirlo. Sin una prueba que comprobara que seguía corregido, nada impedía que volviera.
Organizo las pruebas en tres niveles. Sitúo los permisos, los datos inválidos y los fallos externos en el nivel más barato que me permite comprobar el comportamiento completo.
Con pruebas unitarias compruebo funciones y clases con datos concretos, sin interfaz. Son rápidas, estables y baratas, así que concentro en ellas el grueso de las pruebas: cálculos, reglas de negocio, transformaciones y casos límite.
Compruebo que la extensión funciona bien con la base de datos, los eventos y las interfaces del núcleo. Estas pruebas son más lentas, pero detectan si un cambio de versión ha roto algo.
Con estas pruebas simulo el recorrido de una persona por la plataforma. Escribirlas y mantenerlas tiene un coste alto, así que las reservo para los recorridos que no pueden fallar: acceder, hacer un cuestionario, calificar y matricularse.
Me hago cinco preguntas para evitar una batería de pruebas grande e inútil.
Introduzco un fallo controlado en el comportamiento exacto que la prueba afirma proteger. Si entonces sigue en verde, la prueba no está comprobando ese comportamiento.
No duplico las pruebas internas del núcleo. Desde la extensión sí pruebo las interfaces y los comportamientos de Moodle que la propia extensión necesita para funcionar.
Siempre pruebo lo que afecta a calificaciones, accesos o datos. Casi nunca pruebo lo cosmético.
Compruebo que alguien sin derechos no puede hacer la operación y que quien los tiene sí puede. Ambas pruebas son igual de importantes, pero la negativa suele faltar.
Asigno esa responsabilidad a una persona concreta. Si no lo hago, las pruebas inestables se desactivan una a una hasta que la suite deja de significar algo.
La primera señal es la que más veces me ha revelado que una batería de pruebas no sirve.
Seis problemas que detecto cuando las pruebas cuestan más de lo que aportan.
Descarto las pruebas que ejecutan el código sin verificar nada o que solo verifican algo trivial: dan cobertura, pero ninguna protección.
He visto cómo el equipo deja de prestar atención a los fallos en cuanto una batería de pruebas falla de forma intermitente sin que exista un defecto real. A partir de ahí, la batería ya no sirve.
Preparo y limpio los datos de cada prueba para que el orden de ejecución no importe. Así, un cambio no rompe pruebas sin relación.
Evito verificar textos exactos y rutas frágiles de la interfaz, porque un cambio visual puede romper pruebas que no guardan relación con él.
Si pruebo solo los casos que van bien, cubro justo los que menos fallan en producción. Empiezo por las excepciones.
Si la suite completa tarda una hora, solo la ejecuto el día del despliegue, no cuando todavía sirve de algo.
Ajusto la inversión a lo que hay en juego si algo se rompe.
Empiezo por pruebas unitarias sobre la lógica propia. Añado pruebas por interfaz cuando la extensión cambia un recorrido crítico, depende mucho de JavaScript o un fallo tendría consecuencias relevantes; el tamaño del código no basta para descartarlas.
Añado pruebas de integración: detectan los fallos en la interacción entre piezas que no aparecen al probar cada pieza por separado.
Ejecuto las pruebas automáticamente con cada cambio y corrijo cualquier inestabilidad el mismo día. Sin esa disciplina, el conjunto de pruebas se degrada en cuestión de meses.
Entonces las pruebas acotan con rapidez qué comportamientos cubiertos han fallado, en lugar de obligarme a descubrirlos todos mediante comprobaciones manuales.
Fijo seis requisitos para evitar una batería de pruebas decorativa.
| Requisito | Evidencia exigible | Criterio de aceptación |
|---|---|---|
| Pruebas de la lógica propia | Batería de pruebas ejecutable con la herramienta oficial de la plataforma | La organización ejecuta todas las pruebas sin ayuda y obtiene un resultado correcto en todas |
| Pruebas de integración con Moodle | Casos que prueban la base de datos, los eventos y las interfaces utilizadas | Ejecutar los casos acordados en cada versión objetivo y detectar los fallos de integración |
| Pruebas de los recorridos críticos | Pruebas funcionales de los flujos acordados | Cubrir los recorridos acordados y ejecutar sus pruebas en la entrega |
| Pruebas de permisos | Casos de prueba con un rol sin autorización | Comprobar que la operación también se deniega, no solo que se permite |
| Pruebas que detectan roturas | Demostración: las pruebas fallan después de alterar el código a propósito | Cada prueba falla cuando se rompe lo que comprueba |
| Ejecución reproducible | Instrucciones y entorno para ejecutarlas | La organización ejecuta por su cuenta el conjunto completo de pruebas |
Las métricas pueden parecer buenas, pero dejo huecos importantes si persigo el porcentaje de cobertura, pruebo solo el recorrido previsto o ejecuto toda la batería de pruebas desde la interfaz.
Cubrir líneas no me demuestra que el comportamiento sea correcto. Verifico los resultados de la función, porque una prueba puede ejecutar todas sus líneas sin comprobar ninguno.
Con datos correctos y una persona con permisos, todo va bien. Pruebo también los demás casos: si solo sigo el recorrido previsto, no los cubro y no veo sus fallos.
Descarto automatizar cada pantalla. Las pruebas por interfaz son lentas y frágiles, y una batería completa tarda horas, da fallos por motivos ajenos y acaba desactivada.
Referencias
Instalación, configuración y ejecución de la suite de pruebas unitarias de la plataforma. Consultado el 1 de agosto de 2026.
Mecanismo oficial de pruebas de aceptación que recorren la plataforma como una persona. Consultado el 1 de agosto de 2026.
Generadores de datos y convenciones para pruebas de extensiones. Consultado el 1 de agosto de 2026.
La proporción recomendada entre capas y el criterio de qué merece la pena automatizar son propios, formados escribiendo y manteniendo suites concretas: no proceden de una recomendación oficial. Las herramientas y su configuración están en la documentación enlazada y cambian entre versiones. La comprobación de que una prueba falla al romper el código a propósito es una práctica conocida en ingeniería de software; aquí la presento porque es la que más veces destapa suites que no protegen.
Blog
En el blog desarrollo casos particulares, pruebas y fuentes que amplían esta página de referencia.
Ir a blog.albertolarah.comContacto
Suele significar que la batería no comprueba lo que hace falta, o que se ha vuelto inestable. Reviso qué comprueba, cuánto tarda en ejecutarse, con qué frecuencia falla sin causa aparente y qué pasó la última vez que algo se rompió en producción.
hola@albertolarah.comLinkedIn ↗