Guía práctica para escribir tests usando inteligencia artificial
18 September 20268 min de lectura
Escribir tests que sirven de verdad: guía práctica para equipos que despliegan los viernes
Escribir tests es una de esas tareas que todo el mundo dice valorar y muy pocos ejecutan con criterio. El resultado habitual son suites infladas, lentas y frágiles que nadie mantiene, o peor: cero cobertura y un despliegue cada dos semanas rezando para que nada explote en producción. La diferencia entre una suite útil y una que estorba no está en la cantidad de líneas, sino en las decisiones que tomas antes de escribir la primera aserción. En este tutorial vamos a pasar de la teoría a la práctica con ejemplos concretos, métricas que importan en 2026 y errores que puedes evitar desde hoy.
Define qué vas a probar antes de tocar el teclado
La mayoría de los tests malos no nacen de un framework equivocado, sino de no haber decidido qué comportamiento se está validando. Un test es una especificación ejecutable: si no puedes resumir en una frase qué garantiza, probablemente estás probando la implementación en lugar del comportamiento. La distinción importa porque probar detalles internos hace que cualquier refactor rompa veinte tests sin que nada se haya roto funcionalmente.
Antes de escribir, plantéate tres preguntas: ¿qué entrada produce qué salida?, ¿qué pasa en los bordes (valores nulos, listas vacías, números negativos, cadenas con acentos)?, y ¿qué dependencias externas entran en juego? Esa tercera pregunta determina si necesitas un mock o un contenedor real. Como regla práctica, solo simula lo que no controlas y no puedes levantar en el entorno de pruebas: APIs de terceros, pasarelas de pago, servicios de correo. La base de datos, si puedes, levántala de verdad con Testcontainers o un contenedor efímero en CI.
En cuanto a cobertura, deja de mirar el porcentaje de líneas como si fuera una nota de examen. Una cobertura del 85 % con tests que solo verifican que la función no lanza excepción vale menos que un 60 % con aserciones significativas. Lo que sí conviene medir en 2026 es la **mutation score** mediante herramientas como Stryker (JS/TS, C#), mutmut o Cosmic Ray (Python). Si tus mutaciones sobreviven en un 40 %, tus tests están decorando, no protegiendo.
Prompt
Actúa como ingeniero de calidad senior. Para la función [nombre y descripción de la función], genera una tabla con los casos de prueba que debo cubrir: camino feliz, valores límite, entradas inválidas y casos de negocio ambiguos. Para cada caso indica la entrada, la salida esperada y el riesgo que mitiga. No escribas código todavía.
La pirámide aplicada: unitarios, integración y extremo a extremo
La pirámide clásica (muchos unitarios, algunos de integración, pocos end-to-end) sigue vigente, pero con matices. En proyectos con microservicios o frontends modernos, la proporción útil se parece más a 60/30/10. Los unitarios te dan velocidad de feedback: deben correr en menos de cinco segundos en total. Los de integración validan contratos reales entre módulos y suelen ser los que atrapan los bugs más caros. Los end-to-end, con Playwright o Cypress, se reservan para flujos críticos de negocio: registro, pago, login.
Ejemplo real: un equipo de e-commerce tenía 340 tests unitarios sobre la lógica de precios y descuentos, pero cada release rompía el flujo de aplicación de cupones. El problema no era falta de tests, sino ausencia de un test de integración que ejercitara la cadena completa: aplicación del cupón, cálculo del IVA por país y persistencia del pedido. Añadieron ocho pruebas de integración y las incidencias en producción cayeron un 70 % en dos meses.
El otro ejemplo: una API en FastAPI con PostgreSQL. En lugar de simular el ORM con mocks frágiles, el equipo usó contenedores efímeros por suite. Los tests tardaban 40 segundos más, pero detectaron tres migraciones defectuosas antes de llegar a staging. Ese coste se paga solo.
Prompt
Diseña una estrategia de testing para un proyecto [tipo de proyecto: API REST / SPA / app móvil] con este stack [tecnologías]. Indica qué probar en unitarios, qué en integración y qué en end-to-end, con la proporción recomendada y las herramientas concretas para cada nivel. Justifica por qué cada flujo crítico merece un test E2E.
Escribe tu primer test con estructura clara
Cuando ya sabes qué probar, el cómo es mecánico. Usa siempre la estructura Arrange–Act–Assert: prepara el estado, ejecuta la acción, verifica el resultado. Un test sin esta separación se convierte en un bloque de veinte líneas donde nadie sabe qué falló cuando se rompe.
Pongamos un caso concreto en Python con pytest 8.x. Tienes una función `calcular_descuento(precio, cupon)` que aplica un porcentaje fijo si el cupón es válido y lanza `CuponInvalidoError` si no lo es. Un buen test parametrizado cubriría al menos cuatro combinaciones: cupón válido con precio normal, cupón válido con precio cero, cupón expirado y cupón inexistente. Con `@pytest.mark.parametrize` escribes un solo test que cubre los cuatro casos y, cuando falla, el reporte te dice exactamente qué combinación rompió.
En el frontend la lógica es análoga. Con Vitest 3 o Jest 30, un componente que muestra el total del carrito se prueba verificando el texto renderizado, no el estado interno del hook. Eso te permite refactorizar el componente entero sin tocar el test.
Un detalle que marca la diferencia: nombra los tests describiendo el comportamiento esperado. `test_aplica_descuento_cuando_cupon_es_valido` comunica mucho más que `test_calcular_descuento_1`. Cuando dentro de seis meses alguien vea fallar ese test en CI, sabrá en dos segundos qué se rompió.
Si trabajas con asistentes como ChatGPT-5, Claude Opus 4.5 o Gemini 3 Pro, úsalos para generar el esqueleto y los casos límite, pero revisa siempre las aserciones. Los modelos tienden a generar tests que validan lo que el código hace, no lo que debería hacer. Ese sesgo es peligroso: convierte tu suite en un espejo de los bugs.
Prompt
Tengo esta función: [pega el código]. Escribe tests con [framework: pytest / Vitest / JUnit] usando parametrización. Cubre camino feliz, valores límite y excepciones. Nombra cada test describiendo el comportamiento. No modifiques la función original; si detectas un bug, señálalo en un comentario aparte.
Los errores que arruinan una suite de tests
El primer error es probar la implementación en lugar del comportamiento. Si tu test verifica que se llamó a `repositorio.guardar()` tres veces, cualquier cambio en la capa de persistencia lo rompe aunque el resultado sea idéntico. Testea el efecto observable.
El segundo es el exceso de mocks. Simular cada dependencia produce tests que pasan en verde mientras la integración real falla en producción. La regla: simula solo lo que no puedes ejecutar en el entorno de pruebas.
El tercero son los tests frágiles por dependencia del tiempo o del orden. Si usas `datetime.now()` sin inyectar un reloj, tu test fallará el último día del mes. Si tus tests comparten estado en la base de datos, fallarán según el orden de ejecución. Solución: inyecta el tiempo como dependencia y aísla cada test con transacciones revertidas o bases efímeras.
El cuarto, y quizá el más silencioso: aserciones débiles. Un test que solo comprueba `assert resultado is not None` no prueba nada. Verifica el valor exacto, el tipo y, cuando aplique, el mensaje de error.
Por último, no conviertas la cobertura en un objetivo de equipo. Cuando la métrica se premia, la gente escribe tests vacíos para subir el número. Mide mutation score y tiempo de feedback, no porcentaje.
Prompt
Revisa estos tests: [pega los tests]. Señala cuáles validan implementación en lugar de comportamiento, cuáles tienen aserciones débiles, cuáles son frágiles por tiempo u orden de ejecución, y propón una versión refactorizada de cada uno.
Conclusión: empieza por un test, no por cien
Escribir tests bien no requiere reescribir tu proyecto entero ni adoptar la última herramienta de moda. Requiere decidir qué comportamiento importa, elegir el nivel adecuado de la pirámide y mantener las aserciones honestas. Empieza mañana mismo con un solo test sobre la función más crítica de tu código, el que más miedo te da tocar. Ejecútalo en CI, haz que falle una vez a propósito para comprobar que detecta el fallo, y solo entonces escribe el segundo. Tu yo de dentro de seis meses, desplegando un viernes a las seis de la tarde, te lo agradecerá.
Pack de Programación
10 prompts premium listos para copiar y pegar con ChatGPT, Claude y Gemini. Resultados inmediatos desde el primer uso.