Pruebas que sí atrapan errores: más allá de la cobertura y del quality gate en verde
Por Dorian Chávez · fundador de Hábil y arquitecto de integración ·
Cobertura alta y quality gate en verde no bastan: tipos de prueba, dobles que esconden fallas, mutación, IA y documentación para pruebas que sí atrapan errores.
Escenario ilustrativo. Un equipo de pagos de una fintech abre el tablero un viernes: la cobertura de pruebas está en 91 %, el análisis de calidad de código marca verde y el pipeline —la línea automática que construye, prueba y entrega el software— terminó sin errores. El lunes, un grupo de clientes reporta cargos duplicados. Nadie mintió y ninguna herramienta falló: cada una midió lo que sabe medir. Lo que nadie había medido es si las pruebas, que eran muchas, habrían avisado de ese defecto en particular.
Este artículo es para quien responde por esa diferencia: el CTO o el director de tecnología de un banco, una fintech, una aseguradora, una cadena de retail o una empresa regulada. Explica qué mide realmente la cobertura y el quality gate (la «compuerta de calidad»: un conjunto de condiciones que el código debe cumplir para avanzar), qué tipos de prueba existen y qué falla atrapa cada uno, cómo se comprueba que una prueba sirve, qué papel juegan la inteligencia artificial y la documentación del código, y por dónde empezar. Incluye lo que hemos medido en nuestra propia plataforma, porque algunos de esos hallazgos fueron incómodos.
Qué mide realmente un tablero en verde
Conviene empezar por lo que dicen las propias herramientas.
La cobertura responde una sola pregunta: ¿esta línea de código se ejecutó mientras corrían las pruebas? SonarQube, una herramienta de análisis de calidad de código, define la cobertura de líneas como líneas cubiertas entre líneas ejecutables, y la de condiciones como las ramas verdaderas y falsas recorridas entre el doble de condiciones [11]. Ejecutar una línea no es comprobar que hace lo correcto: una prueba sin ninguna verificación (una «aserción», la comparación entre lo que se esperaba y lo que ocurrió) puede subir la cobertura sin atrapar nada.
El quality gate de SonarQube es un conjunto de condiciones configurables. El predeterminado, llamado «Sonar way», pide en el código nuevo: sin problemas nuevos, cobertura de al menos 80 %, duplicación de 3 % o menos y los puntos sensibles de seguridad revisados [10] [Dato de Sonar: valores por defecto del proveedor]; cada organización los ajusta. La cobertura de líneas solo dice si una línea se ejecutó; la métrica total de Sonar combina líneas y condiciones. Además, Sonar no genera la cobertura: la importa de otra herramienta que corre las pruebas antes del análisis [12]. De lo que mide se deduce lo que no hace: no ejecuta una transferencia, ni una conciliación, ni una emisión de póliza, ni un pago en el comercio electrónico. Esa lectura es nuestra, no una frase de Sonar, pero es coherente con lo que su documentación describe.
Tampoco hay una cifra mágica de cobertura. Martin Fowler, referente en ingeniería de software, la considera una herramienta para encontrar código sin probar, no una meta; ve razonable una cobertura de ochentas altos o noventas, trata el 100 % como señal de alerta y advierte que imponer un mínimo invita a escribir pruebas vacías para llegar a él [9]. Un estudio académico clásico, de Inozemtseva y Holmes (2014), encontró que la cobertura no tiene una correlación fuerte con la efectividad de un conjunto de pruebas una vez que se descuenta su tamaño [21].
Y el «verde» significa cosas distintas según quién configure la compuerta. En una revisión interna de nuestra plataforma comprobamos que el análisis de un proyecto recién creado aprobaba con 3 condiciones activas, mientras el de uno maduro exigía 14. El mismo color, dos niveles de exigencia muy distintos.
Las dos formas más comunes de falso verde
1. Los dobles que responden lo que usted espera
Para probar rápido, los equipos reemplazan las piezas externas —la base de datos, el proveedor de pagos, otro servicio— por dobles de prueba: imitaciones que responden de forma predefinida. Fowler distingue varios tipos: los stubs (respuestas enlatadas), los fakes (implementaciones simplificadas pero funcionales), los spies (que registran cómo los usaron) y los mocks (que traen expectativas preprogramadas) [8]. Son útiles para que las pruebas corran rápido y aisladas.
El riesgo es sencillo de enunciar: si el doble responde lo que el programador cree que responde el sistema real, la prueba pasa aunque el sistema real responda otra cosa. Un doble puede contestar «200 OK» mientras el proveedor real rechaza el encabezado, la codificación, el certificado o el formato de la fecha. Fowler señala además que las pruebas basadas en mocks quedan más acopladas a la implementación: si usted reorganiza el código sin cambiar lo que hace, esas pruebas se rompen; y si el sistema real cambia, siguen pasando [7].
Por eso las pruebas deben llevarse a conectividad real donde la decisión la toma la dependencia y no su código: la base de datos con su motor real, el bus de mensajes con el suyo, el contrato con el proveedor verificado contra el proveedor. Para las dependencias que pueda contenerizar, herramientas como Testcontainers levantan una base de datos o una cola reales y desechables mientras corre la prueba y las destruyen al terminar; su propia guía propone sustituir las bases en memoria por la base real [13]. Para proveedores externos, siga usando sandbox, contrato o un doble observable: un contenedor no sustituye las credenciales, la homologación ni la autorización de un tercero real.
2. Las pruebas que bendicen el error
Una prueba escrita a partir de lo que el código hace, y no de lo que debe hacer, certifica el defecto. Un ejemplo sencillo: la regla de negocio dice que se bloquean los montos de 10,000 pesos o más, pero el código bloquea solo los mayores a 10,000, y la prueba, escrita mirando el código, verifica el comportamiento actual. Hay cobertura completa, todo está en verde y la regla se incumple. Es un riesgo conocido de las pruebas escritas por personas y, como veremos, un riesgo mayor en las que escribe una IA.
Ninguna de las dos formas se ve en el tablero. Se ven al hacer preguntas distintas a la suite de pruebas, y de eso trata el resto del artículo.
Los tipos de prueba y la falla que cada uno puede atrapar
Ningún tipo de prueba cubre por sí solo todos los riesgos relevantes. Cada tipo puede aportar evidencia que los demás no aportan en ese flujo. Esta es la lista que usamos para explicarlo a un comité:
| Tipo | Qué ejecuta | Qué puede atrapar | Qué no ve | Herramientas de ejemplo |
|---|---|---|---|---|
| Unitaria | Una función o clase aislada | Cálculos, límites, validaciones, reglas locales | Que las piezas encajen entre sí | JUnit, pytest, Go testing, Jest, Vitest |
| Integración con dependencias reales | Su código más una base de datos, un bus o un servicio reales y desechables | Migraciones rotas, consultas que fallan contra el esquema real, serialización, configuración, transacciones | Flujos completos de usuario | Testcontainers |
| Contrato | El consumidor y el proveedor de una API, cada uno contra lo pactado | Un campo renombrado, un tipo cambiado, un encabezado distinto que rompería al consumidor | La lógica interna del proveedor | Pact |
| Colección de API | Solicitudes HTTP contra un ambiente, con verificaciones | Códigos de respuesta, formatos, autenticación, autorización, regresiones de un servicio | El comportamiento interno | Postman, Postman CLI, Newman |
| De navegador (extremo a extremo) | Una persona simulada, el navegador, el frontend y el backend integrados | Rutas, cookies, inicio de sesión, renderizado, flujos críticos | Detalles finos; son lentas y frágiles si se abusa | Playwright |
| De mutación | Su suite contra versiones deliberadamente dañadas del código | Pruebas que ejecutan código sin detectar cambios | Si la regla de negocio en sí es la correcta | PIT (Java), Stryker (JavaScript/TypeScript, C#, Scala) |
Algunas aclaraciones que importan para decidir:
- Contrato. Pact verifica al proveedor que el equipo controla; no valida necesariamente al tercero real. Trabaja «dirigido por el consumidor»: solo se prueba lo que el consumidor realmente usa; el consumidor genera un archivo con sus expectativas y el proveedor lo verifica contra el servicio real [14]. Evita montar pruebas integradas costosas entre dos equipos. Sus propios documentos declaran sus límites: no sirve para pruebas funcionales, de carga, para APIs públicas ni cuando no se controlan ambos lados [14].
- Colecciones de API. Postman permite escribir verificaciones en JavaScript por petición, carpeta o colección [15]. Un dato práctico que pocos mencionan: Newman, el ejecutor de colecciones por línea de comandos, sigue disponible para los flujos existentes, pero su repositorio oficial indica que el desarrollo activo se limita a mantenimiento esencial y que, para flujos nuevos, recomiendan la Postman CLI [16]. Si usted ya tiene colecciones corriendo en Newman, no hay urgencia; si va a empezar, conviene empezar con la herramienta vigente.
- Navegador. Una prueba de navegador no siempre es de extremo a extremo: puede simular a los terceros. Playwright cubre Chromium, WebKit y Firefox, y sus buenas prácticas piden probar lo que ve el usuario, aislar cada prueba y simular los sitios de terceros en lugar de probarlos [17]. Es el tipo más parecido al uso real, y por eso se reserva para pocos recorridos de alto valor.
- Mutación. Se explica en una frase: es sabotear el sistema a propósito para ver si suena la alarma. Se desarrolla más adelante.
Herramientas por capa
| Capa | Herramientas de ejemplo | Para qué |
|---|---|---|
| Backend Java | JUnit, Testcontainers, PIT | Reglas de negocio, integración con infraestructura, mutación del código crítico |
| Backend Python | pytest (con sus fixtures, datos y recursos de apoyo reutilizables) | Reglas, parametrización, integración |
| Backend Go | testing y go test, parte de la librería estándar; admite pruebas de fuzzing (entradas aleatorias) | Unidades, integración, entradas inesperadas |
| Frontend (JavaScript/TypeScript) | Jest o Vitest, con Testing Library | Lógica de interfaz y componentes, probados como los usa una persona |
| Frontend, recorridos completos | Playwright | Flujos críticos y compatibilidad entre navegadores |
| JavaScript/TypeScript, mutación | StrykerJS sobre Jest o Vitest | Detectar pruebas débiles |
Testing Library formula el principio con claridad: cuanto más se parezca una prueba a la forma en que se usa el software, más confianza da [20]. Jest declara que Vite no está soportado oficialmente y sugiere Vitest en ese caso [20]; es un ejemplo de por qué la herramienta se escoge según el resto de su stack, no por moda.
Por qué más tipos de prueba rinden más que más pruebas del mismo tipo
La afirmación correcta no es «mientras más tipos, mejor» sin límite. Es esta: para un riesgo dado, conviene invertir en el tipo de prueba que cubre una clase de falla que todavía nadie ha cubierto.
Diez pruebas unitarias más sobre un redondeo no van a descubrir una migración de base de datos que falla, un contrato HTTP incompatible, una sesión que se pierde entre pantallas o una dependencia que tarda demasiado. Eso lo detectan otros tipos. La evidencia de investigación sobre diversidad de pruebas va en esa línea: criterios que distinguen comportamientos distintos pueden encontrar fallas que los criterios tradicionales no ven, con un costo adicional [23].
La otra mitad del equilibrio es no irse al extremo contrario. Las pruebas de navegador son las más parecidas al uso real, pero también las más lentas y frágiles. Fowler las describe como frágiles, caras de escribir y lentas de correr [1]. En el estudio de Google sobre unos 4.2 millones de pruebas propias, las más grandes fueron más inestables, es decir, pasan y fallan sin que el código cambie; WebDriver y el emulador de Android mostraron tasas superiores al promedio entre las herramientas analizadas, y el propio autor aclara que correlación no es causalidad [5] [Dato de Google, 2017; no universal]. Su guía recomienda, aproximadamente, 70 % de pruebas pequeñas, 20 % de integración y 10 % de extremo a extremo [4] [Dato de Google, 2015; no universal]. Es una orientación de una empresa, no una norma; hay quien sostiene que discutir porcentajes distrae [3]. Fowler y Google recomiendan reservar las pruebas amplias para los riesgos que lo justifican; la proporción depende del sistema, y Fowler advierte que hay excepciones a la pirámide [1][4].
Un ejemplo para un comité: tres mil pruebas unitarias con dobles, sin pruebas de contrato, significan que un campo renombrado en una API rompe a todos sus consumidores en producción sin que ningún tablero avise. Esas mismas tres mil, sin integración real, significan que nadie probó la consulta contra el esquema de verdad. Y si todo lo anterior existe pero ninguna prueba recorre el flujo completo, nadie sabe si el cliente puede terminar su compra. Cada tipo de prueba puede cubrir una clase de falla que las demás no ven; concentrar todo en un tipo es concentrar el riesgo.
Lo que hemos medido en nuestra propia plataforma
Hábil construye una plataforma modular de integración. En una medición reciente, sobre sus 34 servicios, contamos 1,407 clases de prueba y cerca de 9,800 métodos de prueba automatizados (dos formas distintas de contarlos dieron 9,771 y 9,839) [37]. Con esa cantidad uno esperaría estar tranquilo. Estos son aprendizajes, ya corregidos, de casos en que la tranquilidad era injustificada. Los números son nuestros y no han sido auditados externamente.
El pago que se hacía 12 veces. Una prueba de un flujo de pagos se llamaba «no duplica» y estaba en verde. Verificaba un contador interno del propio servicio, no la llamada al proveedor de pagos. Al reescribirla para verificar la llamada real, falló: se esperaba 1 y hubo 2. Con un servidor falso que cuenta cuántas veces lo llaman, 12 intentos simultáneos produjeron 12 pagos. Tras el arreglo, produjeron 1. Obsérvese la diferencia entre dos clases de doble: uno que responde lo que se espera, que esconde el defecto, y uno que registra lo que de verdad le llega, que lo expone.
Los 17 de 19 campos perdidos. Un cambio en una función de extracción de datos pasó toda la suite, que usaba documentos de muestra sintéticos. Con documentos reales, el cambio perdía 3 de 4 campos en un tipo de documento y 17 de 19 en un documento extranjero. Las pruebas no estaban mal escritas: estaban alimentadas con datos que no se parecían a los reales.
El rechazo que cortaba un canal. Un rechazo legítimo del proveedor, repetido varias veces, hacía saltar el cortacircuitos, el mecanismo que corta las llamadas a un servicio que parece caído. El efecto era cortar el canal completo. Estaba presente en 7 servicios. Los dobles de prueba no repetían el rechazo, así que el defecto no tenía por dónde aparecer.
Cinco pruebas verdes que sostenían defectos. Encontramos cinco pruebas en verde que sostenían defectos, de tres tipos: la que bendice el error con nombre explícito, la que simula un desenlace imposible y la demasiado permisiva. Ejercer el sistema real descartó 9 hallazgos propios y confirmó otros: verificar en vivo corrige en las dos direcciones.
El éxito sin trabajo. Dos falsos verdes de medición, de los más traicioneros: una construcción que terminó con el mensaje de éxito sin haber ejecutado ninguna prueba, y una corrida de pruebas pasada por un filtro de texto que interrumpió el proceso a la mitad y reportó 113 y 401 pruebas donde en realidad corrían 518. La salida parecía un conteo válido. Lección: el número de pruebas se lee del informe, no del código de salida de un comando.
Los cinco casos tienen una raíz común: en cada uno, la señal verde estaba bien construida y respondía honestamente a la pregunta que se le hacía. La pregunta era la equivocada.
¿Cómo se sabe si una prueba sirve?
Hay dos respuestas, una artesanal y una automatizada.
La artesanal: revertir el arreglo y ver la prueba en rojo. Si una prueba se escribió para proteger un arreglo, se deshace el arreglo y se corre la prueba: tiene que fallar. Si sigue en verde, no estaba protegiendo nada. Para un defecto nuevo, la regla equivalente es escribir primero la prueba que falla y después arreglar; la guía oficial de Claude Code, por ejemplo, la pide así para los errores [28]. Es barata y exige disciplina. En nuestra plataforma la usamos como vara: las 6 mutaciones manuales que hicimos fueron detectadas.
Hay una trampa más fina que conviene conocer, porque no aparece en la literatura que revisamos: una prueba puede pasar también con el defecto. En uno de nuestros arreglos, el criterio decía «tras el rechazo, el saldo vuelve a su valor previo». Al revisarlo notamos que esa comprobación pasaba igual con el error, porque apartar un monto y devolverlo dejan el mismo número. Lo que de verdad distinguía era el registro de operaciones: con el defecto aparecían dos escrituras; con el arreglo, ninguna. La pregunta que vale la pena hacerle a cada prueba importante es sencilla: ¿pasaría también si el error siguiera ahí?
La automatizada: la prueba de mutación. Herramientas como PIT (para Java) y Stryker (para JavaScript, TypeScript, C# y Scala) modifican automáticamente el código —cambian un «mayor que» por «mayor o igual», invierten una condición, eliminan una llamada— y corren la suite [18][19]. Si alguna prueba falla, el cambio «muere»; si todas pasan, el cambio «sobrevive» y revela una prueba que faltaba. El porcentaje de cambios detectados se llama mutation score: si de 100 sabotajes la suite atrapa 80, el score es 80 %. PIT lo dice con claridad: la cobertura tradicional solo mide qué se ejecuta, no si las pruebas podrían detectar una falla [18]. Un estudio de FSE 2014 encontró que los mutantes son un sustituto válido de las fallas reales para evaluar pruebas [22].
La mutación tiene límites que un CTO debe conocer:
- Es lenta. Por eso conviene aplicarla al código que cambió o al código crítico, no a todo el repositorio; la propia documentación de PIT lo recomienda [18].
- Tiene ruido. Existen «mutantes equivalentes»: cambios que no alteran el comportamiento y que ninguna prueba podría detectar [18]. Un estudio industrial reportó que la detección automática de esos mutantes mejora mucho con un preprocesado previo, lo que indica que el propio control tiene su margen de error [27].
- No certifica el negocio. Si la prueba bendice una regla errónea, puede incluso «matar» el cambio que corrige el código. La investigación respalda usar la mutación como guía, no como indicador único: su relación con los defectos reales depende del tamaño y del contexto de la suite [23].
Por eso la calidad se mide como un conjunto de señales, cada una con su pregunta:
| Señal | Pregunta que responde |
|---|---|
| Cobertura | ¿Qué código se ejecutó? |
| Mutación | ¿Las verificaciones detectan cambios plausibles? |
| Contratos verificados | ¿Consumidor y proveedor siguen siendo compatibles? |
| API y navegador en recorridos críticos | ¿El flujo real funciona en el ambiente objetivo? |
| Trazabilidad entre requisito y prueba | ¿La expectativa viene de una regla aprobada, o de lo que el código ya hacía? |
| Defectos que llegaron a producción | ¿La evidencia sigue prediciendo lo que pasa en producción? |
Aun con conectividad real, pueden pasar cosas
Llevar las pruebas a dependencias reales reduce una clase de riesgo; no lo elimina. Un ambiente de pruebas no es producción: tiene menos datos, otra latencia, otras credenciales y, con frecuencia, otra versión del proveedor. Un tercero puede cambiar su comportamiento sin avisar. Una carga que no se simuló puede mostrar un defecto de concurrencia. Y los flujos que solo ocurren una vez al mes, como el cierre contable o la renovación anual de una póliza, rara vez están en la suite. Este mapa cubre principalmente comportamiento funcional y compatibilidad; desempeño, seguridad y continuidad requieren controles específicos según el riesgo.
Por eso la estrategia sensata tiene dos mitades. La primera, más tipos de prueba automatizada, cada uno apuntado a una clase de falla. La segunda, lo que ocurre después de liberar: observar lo que hace el sistema, poder dar marcha atrás y revisar con calma lo que se escapó. Cada defecto que llega a producción es información: indica qué tipo de prueba faltaba, y la respuesta correcta suele ser agregar esa prueba, no solo corregir el código. Esa conversación, la de liberar con control, la desarrollamos en «Liberar sin miedo en su propia infraestructura».
La inteligencia artificial: acelera, pero necesita un filtro
La IA ayuda a construir pruebas: propone casos límite, genera esqueletos, arma colecciones de API, explica una falla. Su producción tiene un perfil conocido.
Lo que muestra la evidencia. Un estudio industrial de Meta sobre generación de pruebas con modelos de lenguaje midió que el 75 % de los casos compilaba, el 57 % pasaba de forma confiable y el 73 % de las recomendaciones fue aceptado por los ingenieros [Estudio de Meta, muestra específica]; todo esto después de filtros automáticos que descartan lo que no compila, no pasa o no aporta cobertura [24]. Un estudio sobre 25 paquetes de JavaScript halló una mediana de 70.2 % de cobertura de sentencias y 52.8 % de ramas con un modelo de uso general [25]. Son cifras de modelos de 2023 y 2024; las de hoy serán distintas, pero la dirección es instructiva: sin filtros, una parte importante de lo generado no sirve.
El riesgo central. La IA tiende a copiar lo que el código hace, no lo que debe hacer. Un estudio sobre 24 repositorios de Java concluyó que las pruebas generadas con modelos de lenguaje capturan sobre todo el comportamiento actual, lo que dificulta detectar errores [26]. Es la prueba que bendice el error, producida a velocidad de máquina. Otros riesgos documentados: verificaciones superficiales que inflan la cobertura, métodos o reglas inventados, y datos sensibles que salen hacia un tercero. Un estudio histórico sobre un asistente de código encontró vulnerabilidades en alrededor del 40 % de 1,689 programas generados para escenarios específicos; es un resultado de su momento, no una tasa aplicable a los modelos actuales [36].
Qué hacer con eso. Las guías de los proveedores coinciden en lo esencial, aunque ninguna trae cifras propias:
- Dar a la IA una comprobación que ella misma pueda ejecutar; la guía de Claude Code la llama la diferencia entre una sesión que se vigila y una que se deja sola, y pide que muestre la salida de las pruebas en lugar de afirmar que pasaron [28].
- Ser específico al pedir pruebas: «agrega pruebas a este archivo» es el ejemplo malo; el bueno nombra el caso borde y lo que debe evitarse [28].
- Revisar lo generado y agregar las pruebas que falten, como indica la guía de GitHub Copilot [30].
- Vigilar el «verde a la fuerza»: la guía de Anthropic advierte que el modelo puede enfocarse en que las pruebas pasen, incluso con valores fijos, y recuerda que las pruebas están para verificar la corrección, no para definir la solución [29].
- Separar a quien escribe de quien revisa. La guía de Claude Code sugiere sesiones distintas para escribir las pruebas y para escribir el código que las satisface [28].
- No cargue datos de producción en herramientas de IA ni en ambientes de prueba sin clasificación, enmascaramiento (o datos sintéticos) y validación de privacidad, y revise con su proveedor la retención y las condiciones contractuales.
- Pasar lo generado por la mutación: dar a la IA los mutantes que sobrevivieron permitió detectar hasta 28 % más fragmentos defectuosos de código escrito por personas que la línea base, en un estudio [27].
La política que resume todo es corta: la IA propone; la ejecución, la mutación y la revisión del dominio validan.
Por qué documentar el código mejora las pruebas
El código solo dice lo que hace. Lo que debe hacer vive en otro lugar, y si no está escrito, la IA —y la persona nueva en el equipo— lo deduce de la implementación y copia sus errores. Ahí entra la documentación.
Los comentarios de documentación —Javadoc en Java, JSDoc y TSDoc en JavaScript y TypeScript, docstrings en Python— son, en la práctica, un contrato: qué recibe una función, qué devuelve, qué excepciones puede lanzar, qué efectos secundarios tiene [34]. La convención de Python (PEP 257) pide documentar comportamiento, argumentos, retorno, efectos secundarios, excepciones y restricciones de uso [34]. Además, doctest convierte los ejemplos escritos en el docstring en pruebas ejecutables: si un ejemplo deja de ser cierto, la suite lo dice [34]; lo que el docstring explica fuera de esos ejemplos sí puede desactualizarse en silencio.
¿Qué tanta evidencia hay de que esto mejora las pruebas? La respuesta honesta es: apunta en esa dirección, aunque no hemos encontrado un experimento limpio de «mismo código con y sin documentación». Lo que sí hay son estudios cercanos: convertir documentación en lenguaje natural a condiciones verificables con un modelo de lenguaje permitió atrapar 64 errores históricos reales [33]; extraer reglas de la documentación de APIs de aprendizaje profundo halló 94 errores frente a 59 de la línea base sin esas restricciones [33]; y un estudio de generación de verificaciones encontró mejoras de 10 a 20 % al incorporar Javadoc [31]. La advertencia va en el otro sentido: documentación falsa o desactualizada puede perjudicar seriamente la comprensión del código por parte de un modelo [32]. No basta con documentar; hay que mantener lo documentado correcto.
El tercer elemento son los archivos de contexto del repositorio, como AGENTS.md (formato abierto que leen varios asistentes de código, entre ellos Codex y Copilot) o CLAUDE.md en el caso de Claude Code [35]. Ahí se escriben los comandos para correr las pruebas, las convenciones y las trampas que no se deducen leyendo el código. Dos recomendaciones oficiales: que sean cortos, porque si son largos el asistente ignora reglas, y que no sustituyan los requisitos aprobados ni contengan secretos [28][35].
En nuestra plataforma documentamos el código para que una persona nueva pueda orientarse sin ayuda. No tenemos medido que eso haya mejorado las pruebas que escriben los asistentes, y no lo afirmamos. Lo que sí medimos es el costo de no escribirlo: la documentación ya decía que cierta opción de configuración no se ejercitaba fuera de su valor por omisión, y el hueco apareció de todos modos. De ahí salió una regla práctica: una prueba de configuración debe demostrar las dos direcciones, no solo la usual.
Ejemplos sencillos por industria
Todos son escenarios ilustrativos, sin clientes ni cifras.
| Industria | Escenario | Qué combinación de pruebas lo atrapa |
|---|---|---|
| Banca | Una transferencia se duplica cuando la app reintenta tras una conexión cortada | Unitaria de la idempotencia (que repetir la misma operación no la aplique dos veces: reintentar no repite); integración con la base real para comprobar que la restricción de unicidad funciona; contrato con el servicio de pagos; recorrido de navegador de transferencia a comprobante |
| Fintech | Un depósito se acredita dos veces cuando el proveedor repite el aviso | Unitaria de la llave de idempotencia y los montos; integración con el libro de saldos real; contrato del aviso; colección de API para la firma inválida |
| Seguros | La cotización aplica un deducible equivocado justo en la edad límite | Unitaria con las edades de frontera (70 y 71, con y sin examen médico); mutación del motor de tarifas, porque ahí un «mayor que» por «mayor o igual» cambia primas; recorrido de cotización a emisión |
| Retail | El checkout vende la última pieza a dos clientes a la vez | Integración con el inventario real y concurrencia; contrato con pagos; unas pocas pruebas de navegador del recorrido de compra, con la pasarela externa simulada |
| Empresa regulada | Un reporte regulatorio muestra un total mal agregado | Unitarias de las reglas de cálculo; integración contra el esquema real; mutación sobre la lógica de agregación; un requisito escrito en el contexto del repositorio que exija una prueba de enmascaramiento de datos personales en bitácoras |
Tome el de banca. La unitaria dice que la lógica es correcta; la de integración demuestra que la base rechaza el duplicado de verdad; la de contrato dice que el servicio de pagos entiende la misma identificación; la de navegador, que la persona ve un comprobante. Ninguna de las cuatro, sola, aporta la evidencia de las otras tres.
Por dónde empezar
- Mida lo que ya tiene, de dos formas. Cuente sus pruebas del informe de la corrida, no del código de salida, y compárelo con otro método. Revise qué condiciones activas tiene su quality gate en cada proyecto y si son las mismas.
- Elija sus cinco flujos con más dinero o más regulación en juego —un pago, una emisión, una conciliación, un reporte— y pregunte de cada uno: ¿qué tipo de prueba lo atraparía si se rompe y existe hoy?
- Revise sus dobles. Donde decide la dependencia (base, bus, proveedor), pase de un doble que responde lo esperado a una dependencia real o a un doble que registra lo que de verdad llega.
- Pruebe sus pruebas. Elija las diez más importantes: revierta el arreglo y compruebe que se ponen en rojo. En el código crítico, evalúe una herramienta de mutación acotada a lo que cambia.
- Ponga a la IA dentro del mismo control. Que muestre la salida de las pruebas, que no cierre una tarea con verificaciones vacías y que cada prueba generada tenga un requisito escrito detrás.
- Escriba lo que el sistema debe hacer donde los asistentes lo lean: documentación de las reglas críticas y un archivo de contexto corto con los comandos y las trampas.
En un diagnóstico, con alcance acordado, podemos construir un mapa de sus flujos críticos, la evidencia existente y las brechas priorizadas. No sustituye una certificación de ausencia de defectos ni de cumplimiento. ¿Cuántas de las pruebas que hoy sostienen su verde se ponen en rojo si se revierte el arreglo? Ese es el siguiente paso natural: el diagnóstico puede empezar por responderlo con sus propios flujos.
Referencias
- M. Fowler, Test Pyramid (2012). https://martinfowler.com/bliki/TestPyramid.html
- H. Vocke, The Practical Test Pyramid (2018). https://martinfowler.com/articles/practical-test-pyramid.html
- K. C. Dodds, The Testing Trophy and Testing Classifications (2018). https://kentcdodds.com/blog/the-testing-trophy-and-testing-classifications
- Google Testing Blog, Just Say No to More End-to-End Tests (2015). Guía de una empresa, cifras aproximadas. https://testing.googleblog.com/2015/04/just-say-no-to-more-end-to-end-tests.html
- Google Testing Blog, Where do our flaky tests come from? (2017). Dato de Google, no universal. https://testing.googleblog.com/2017/04/where-do-our-flaky-tests-come-from.html
- Google Testing Blog, Test Sizes (2010). https://testing.googleblog.com/2010/12/test-sizes.html
- M. Fowler, Mocks Aren't Stubs. https://martinfowler.com/articles/mocksArentStubs.html
- M. Fowler, Test Double. https://martinfowler.com/bliki/TestDouble.html
- M. Fowler, Test Coverage. https://martinfowler.com/bliki/TestCoverage.html
- SonarQube, Introduction to quality gates (valores por defecto del proveedor, configurables), consultado el 6-oct-2026. https://docs.sonarsource.com/sonarqube-server/quality-standards-administration/managing-quality-gates/introduction-to-quality-gates
- SonarQube, Metrics definition (cobertura de líneas y de condiciones), consultado el 6-oct-2026. https://docs.sonarsource.com/sonarqube-server/user-guide/code-metrics/metrics-definition
- SonarQube, Test coverage overview, consultado el 6-oct-2026. https://docs.sonarsource.com/sonarqube-server/analyzing-source-code/test-coverage/overview
- Testcontainers, documentación y guías, consultado el 6-oct-2026. https://java.testcontainers.org/ · https://testcontainers.com/guides/
- Pact, documentación (How Pact works, What is Pact good for), consultado el 6-oct-2026. https://docs.pact.io/ · https://docs.pact.io/getting_started/what_is_pact_good_for
- Postman, Test scripts y Postman CLI overview, consultado el 6-oct-2026. https://learning.postman.com/docs/tests-and-scripts/write-scripts/test-scripts/ · https://learning.postman.com/docs/postman-cli/postman-cli-overview/
- Newman, repositorio oficial (README: mantenimiento limitado; Postman CLI para flujos nuevos), consultado el 6-oct-2026. https://github.com/postmanlabs/newman
- Playwright, Introduction, Best practices y Mock APIs, consultado el 6-oct-2026. https://playwright.dev/docs/intro · https://playwright.dev/docs/best-practices · https://playwright.dev/docs/mock
- PIT Mutation Testing, sitio, mutadores y FAQ, consultado el 6-oct-2026. https://pitest.org/ · https://pitest.org/faq/
- Stryker Mutator, documentación, consultado el 6-oct-2026. https://stryker-mutator.io/docs/
- Documentación oficial de JUnit, pytest, Go
testing, Jest, Vitest y Testing Library, consultado el 6-oct-2026. https://docs.junit.org/current/user-guide/ · https://docs.pytest.org/en/stable/ · https://pkg.go.dev/testing · https://jestjs.io/docs/getting-started · https://vitest.dev/guide/ · https://testing-library.com/docs/ - L. Inozemtseva y R. Holmes, Coverage Is Not Strongly Correlated with Test Suite Effectiveness, ICSE 2014. https://dl.acm.org/doi/10.1145/2568225.2568271
- R. Just et al., Are Mutants a Valid Substitute for Real Faults in Software Testing?, FSE 2014. https://dl.acm.org/doi/10.1145/2635868.2635929
- M. Papadakis et al., mutación y defectos reales, ICSE 2018 (https://doi.org/10.1145/3180155.3180183); Shin, Papadakis y Kintis, diversidad de pruebas y mutación, IEEE TSE (https://doi.org/10.1109/TSE.2017.2732347).
- N. Alshahwan et al., Automated Unit Test Improvement using Large Language Models at Meta, FSE 2024, arXiv 2402.09171. https://arxiv.org/abs/2402.09171
- Schäfer et al., An Empirical Evaluation of Using Large Language Models for Automated Unit Test Generation, arXiv 2302.06527. https://arxiv.org/abs/2302.06527
- Estudio de oráculos de prueba generados con modelos de lenguaje (24 repositorios Java), arXiv 2410.21136. https://arxiv.org/abs/2410.21136
- Pruebas con modelos de lenguaje y mutación: arXiv 2308.16557 (mutantes sobrevivientes en el prompt, hasta 28 % más de fragmentos defectuosos detectados) y arXiv 2501.12862 (mutación dirigida en la industria). https://arxiv.org/abs/2308.16557 · https://arxiv.org/abs/2501.12862
- Anthropic, Claude Code, Best practices y Memory, consultado el 6-oct-2026. https://code.claude.com/docs/en/best-practices · https://code.claude.com/docs/en/memory
- Anthropic, Claude prompting best practices, consultado el 6-oct-2026. https://platform.claude.com/docs/en/build-with-claude/prompt-engineering/claude-prompting-best-practices
- GitHub, Copilot: write tests y Best practices, consultado el 6-oct-2026. https://docs.github.com/en/copilot/tutorials/write-tests · https://docs.github.com/en/copilot/get-started/best-practices
- Liu et al., Doc2OracLL, 2025. https://doi.org/10.1145/3729354
- Macke y Doyle, documentación y comprensión de código por modelos de lenguaje, NAACL Findings 2024. https://aclanthology.org/2024.findings-naacl.66/
- Documentación como insumo de pruebas: arXiv 2310.01831 (nl2postcond: lenguaje natural a condiciones verificables, 64 errores históricos reales de Defects4J) y arXiv 2109.01002 (DocTer: reglas extraídas de la documentación de APIs de aprendizaje profundo, 94 errores frente a 59 de la línea base). https://arxiv.org/abs/2310.01831 · https://arxiv.org/abs/2109.01002
- Oracle, especificación de comentarios Javadoc; JSDoc; TSDoc; PEP 257; documentación de
doctest, consultado el 6-oct-2026. https://docs.oracle.com/en/java/javase/21/docs/specs/javadoc/doc-comment-spec.html · https://jsdoc.app/about-getting-started · https://tsdoc.org/ · https://peps.python.org/pep-0257/ · https://docs.python.org/3/library/doctest.html - AGENTS.md (formato abierto) y documentación de Codex y GitHub Copilot sobre instrucciones del repositorio, consultado el 6-oct-2026. https://agents.md/ · https://learn.chatgpt.com/docs/agent-configuration/agents-md · https://docs.github.com/en/copilot/reference/custom-instructions-support
- Pearce et al., Asleep at the Keyboard? Assessing the Security of GitHub Copilot’s Code Contributions, IEEE Symposium on Security and Privacy, 2022 (https://doi.org/10.1109/SP46214.2022.9833571); versión en Communications of the ACM, 2025 (https://doi.org/10.1145/3610721).
- Hábil, mediciones propias sobre su plataforma modular (34 servicios), 2026. Experiencia de la casa, sin auditoría externa.
- Nube e infraestructura →
- Liberar sin miedo en su propia infraestructura →
- APIs listas para agentes de IA →
¿Su operación tiene estos desafíos?
¿Prefiere correo? Escríbanos a hola@habil.mx