🧪 Pruebas de Software: antes vs hoy

Cómo se probaba el código tradicionalmente ("a ojo", recargando el navegador, mirando la pantalla) y cómo se prueba hoy (automatizado, sin manos, en segundos). Enfocado en MySQL, PHP, Python, HTML, CSS, Bootstrap, Tailwind y JavaScript.

🕰️ Testing tradicional 🚀 Testing moderno Comparador de código Quiz 10/50 🤖 IA en el testing

📖 Teoría

Probar software es comprobar, de forma deliberada, que un programa hace lo que se supone que debe hacer — y que no hace lo que no debe (romperse, borrar datos, dejar pasar a alguien sin permiso).

  • Verificación: ¿el software se construyó correctamente? (¿el código hace lo que el diseño dice?)
  • Validación: ¿se construyó el software correcto? (¿resuelve el problema real del usuario?)

La regla del costo del error:

Un error encontrado mientras escribes el código cuesta minutos. El mismo error encontrado en producción, con clientes usando el sistema, puede costar horas, dinero, datos perdidos y confianza. Por eso probar no es un paso extra: es parte de programar.

Durante décadas (y todavía en muchos proyectos pequeños) probar significaba una persona haciendo clic y mirando la pantalla:

  • Escribir el código, guardar, recargar el navegador (F5) y mirar "¿se ve bien?".
  • Imprimir variables con echo, var_dump(), print() o console.log() para ver "qué hay adentro".
  • Probar al final del proyecto, en una fase separada, muchas veces por otra persona (QA) con una lista en papel o Excel.
  • Repetir el mismo clic, 20 veces, cada vez que se toca el código (y a veces olvidarlo).
  • La frase típica: "en mi máquina funciona" — porque nadie probó en las condiciones reales del usuario.

💡 No es que estuviera "mal" — así se hacía con las herramientas de la época. El problema es que es lento, se olvida, y depende 100% de la memoria y el cuidado humano.

Hoy, la prueba es código que prueba código: se escribe una vez y se ejecuta automáticamente, cientos de veces, sin cansarse ni olvidarse.

  • Pruebas automatizadas: un programa (PHPUnit, pytest, Jest…) ejecuta el código y compara el resultado contra lo esperado.
  • TDD (Test-Driven Development): se escribe primero la prueba (que falla), luego el código mínimo para que pase, y se refactoriza.
  • BDD (Behavior-Driven Development): se describe el comportamiento en lenguaje casi natural ("Dado que… cuando… entonces…").
  • Shift-left testing: probar lo más temprano posible (mientras se escribe el código), no dejarlo para el final.
  • CI/CD (Integración y Despliegue Continuos): cada vez que subes código, un robot corre TODAS las pruebas automáticamente antes de publicar.

💡 El objetivo no cambió (asegurar que el software funcione) — lo que cambió es quién hace el trabajo repetitivo: antes una persona, hoy una máquina.

El testing moderno organiza las pruebas en capas, según cuántas conviene tener de cada una:

🔺 E2E — pocas, lentas, caras (simulan al usuario completo)
🔷 Integración — algunas (varios módulos juntos)
🟪 Unitarias — muchísimas, rápidas, baratas (una función)

Mientras más abajo en la pirámide, más rápidas y baratas son las pruebas — por eso debe haber muchísimas. Mientras más arriba, más realistas pero más lentas y frágiles — por eso debe haber pocas, solo para los flujos más importantes.

💡 Un error común es hacer la pirámide "al revés": muchas pruebas E2E lentas y pocas unitarias — el proyecto se vuelve lento de probar y frágil.

Antes: tras cada cambio, abrir phpMyAdmin, ejecutar un SELECT y mirar fila por fila si "se ve bien". Si algo se dañó, a veces se nota días después — o nunca.

Ahora: existe una base de datos de prueba separada (nunca la de producción), con datos semilla (seeders) de ejemplo. Las pruebas corren dentro de una transacción que se revierte al final (ROLLBACK), así nunca dejan rastro. El programa compara el resultado con assert en vez de "mirar a ojo".

⚠️ Regla de oro: nunca correr pruebas automatizadas contra la base de datos real — podrían borrar o dañar datos de verdad.

Antes: llenar el código de echo y var_dump(), recargar la página en el navegador y comparar el resultado "a ojo" contra lo que el programador cree que debería salir.

Ahora: PHPUnit (instalado con Composer) permite escribir una clase de prueba con métodos como assertEquals(), que comparan el resultado real contra el esperado y avisan solos si algo falla — sin abrir el navegador.

// PHPUnit — se ejecuta con: vendor/bin/phpunit class CarritoTest extends TestCase { public function testCalcularTotal() { $carrito = [['precio'=>50000, 'cant'=>3]]; $this->assertEquals(150000, calcularTotal($carrito)); } }

Antes: correr el script (python app.py), leer la salida en la consola y decidir "a simple vista" si el número o el texto se ve correcto.

Ahora: con pytest (o el módulo unittest incluido en Python) se escriben funciones que empiezan por test_ con instrucciones assert. Se ejecutan con el comando pytest y el reporte de la consola dice exactamente qué pasó y qué falló.

# pytest — se ejecuta con: pytest def test_calcular_promedio(): assert calcular_promedio([10, 20, 30]) == 20.0

💡 Un fixture en pytest es una función que prepara datos o el entorno antes de cada prueba (ej. crear un usuario de prueba).

Antes: abrir el sitio en Chrome, luego en Firefox, luego en el celular, achicando la ventana a mano para ver si el diseño responsive (Bootstrap/Tailwind) se acomoda — todo repetido cada vez que se cambia una línea de CSS.

Ahora: herramientas como Playwright o Cypress abren la página en varios navegadores y tamaños de pantalla a la vez, de forma automática. Existen además:

  • Regresión visual: comparar una captura de pantalla nueva contra una de referencia y avisar si algo cambió sin querer.
  • Lighthouse (de Google): mide rendimiento, accesibilidad, buenas prácticas y SEO automáticamente.
  • axe / linting de accesibilidad: revisa que la página sea usable por personas con discapacidad.

En JavaScript, en vez de alert() y console.log() esparcidos por el código, se usan frameworks como Jest (unitarias) y Cypress/Playwright (end-to-end, simulando clics reales del usuario).

¿Se recomienda usar IA para probar software? — de hecho ya es parte normal del testing moderno. Asistentes como Claude Code, GitHub Copilot o Cursor no reemplazan a PHPUnit, pytest ni Jest: los ayudan a escribirlos.

Para qué se usa la IA en el testing hoy:

  • Generar casos de prueba a partir de una función, incluyendo casos borde que el programador no pensó (valores vacíos, negativos, nulos, textos muy largos).
  • Escribir la clase de prueba completa (PHPUnit/pytest/Jest) a partir de la descripción del comportamiento esperado.
  • Revisar código antes de subirlo, señalando posibles bugs, inyección SQL o falta de validaciones.
  • Correr la suite de pruebas, leer por qué falló una y proponer el arreglo.
  • Generar datos de prueba (seeders) realistas para una base de datos MySQL.

⚠️ La IA acelera escribir pruebas, pero no reemplaza el criterio humano: siempre hay que revisar que la prueba generada verifique realmente lo correcto — una IA puede generar una prueba que "pasa" sin comprobar nada útil. Es una herramienta más de la caja, no un QA automático infalible.

⚖️ Comparador: Antes vs Ahora

Elige una tecnología y mira, con código real, cómo se probaba tradicionalmente y cómo se prueba hoy.

🕰️ ANTES (tradicional)

🚀 AHORA (moderno)

🧭 Explorador de tipos de pruebas

Toca cada tipo para conocer qué verifica y cuándo se usa.

✅ Autoevaluación: ¿pruebas como en 2005 o como hoy?

Marca las prácticas modernas que ya usas en tus proyectos y descubre tu nivel.

📚 Diccionario

QA
Quality Assurance: prácticas para garantizar que el software cumple los requisitos.
TDD
Test-Driven Development: escribir la prueba antes que el código.
BDD
Behavior-Driven Development: describir el comportamiento esperado en lenguaje casi natural.
Prueba unitaria
Verifica una sola función o método, de forma aislada.
Prueba de integración
Verifica que varios módulos funcionan bien juntos.
Prueba E2E
Simula el flujo completo de un usuario real, de principio a fin.
Mock
Objeto simulado que imita una dependencia real (ej. una API) para probar sin usarla de verdad.
Stub
Versión simplificada de una función que devuelve datos fijos durante la prueba.
Aserción (assert)
Instrucción que compara el resultado obtenido con el esperado.
Cobertura de código
Porcentaje del código que las pruebas ejecutan.
CI/CD
Integración y Despliegue Continuos: automatizan pruebas y publicación en cada cambio.
Regresión
Volver a probar que algo que ya funcionaba sigue funcionando tras un cambio.
Caso de prueba
Conjunto de pasos y datos para verificar un comportamiento específico.
Fixture
Datos o estado preparado de antemano para que una prueba corra en condiciones controladas.
Entorno de pruebas
Copia separada de la app/base de datos donde se prueba sin afectar producción.
Shift-left testing
Mover las pruebas lo más temprano posible en el desarrollo, no dejarlas para el final.
IA aplicada al testing
Uso de asistentes como Claude Code para generar pruebas, sugerir casos borde y explicar por qué falló una prueba — siempre bajo revisión humana.

🎬 Videos

¿Qué es y para qué sirve el TDD?

Pruebas unitarias con PHPUnit (PHP + MySQL)

PyTest: pruebas unitarias en Python

Jest — testing en JavaScript para principiantes

📝 Cuestionario

10 preguntas aleatorias del banco de 50. Calificación de 0 a 100.