Piensa mal y acertarás: la mentalidad adversarial en el testing


“Un campo numérico. Tipo decimal. Valor por defecto: 9.0.” La especificación lo describe con precisión quirúrgica: “el usuario podrá configurar ese valor para que el sistema calcule el precio final.” Nada más.

¿Qué hace la mayoría? Comprueba que el campo existe, que acepta el valor 9.0, que el cálculo es correcto. Supera las pruebas; siguiente tarea. ¿Qué hace alguien con mentalidad adversarial? Se hace una pregunta distinta: ¿qué permite este campo que nadie ha pedido que permita?

La respuesta, en este caso, era evidente: admitía valores negativos. Un precio negativo en un contrato real. Y nadie lo había cuestionado porque nadie lo había pedido, pero tampoco nadie lo había prohibido explícitamente. La especificación describía lo que debía ocurrir cuando todo iba bien. No decía nada sobre lo que no debía ocurrir nunca.

El bug existía en el sistema antes de que nadie empezara o siquiera diseñara la primera prueba. No lo encontró una batería de tests exhaustivos. Lo encontró una pregunta incómoda en el momento más temprano posible.

Qué es la mentalidad adversarial

No es pesimismo ni desconfianza hacia el equipo. Es una mentalidad que se entrena: cuando recibes algo para probar, tu trabajo no es confirmar que funciona: es intentar demostrar que puede fallar. La diferencia puede parecer semántica, pero no lo es.

Cuando tu objetivo es confirmar que funciona, ejecutas el flujo principal, verificas los criterios de aceptación y buscas lo que la especificación describe. Cuando tu objetivo es demostrar que puede fallar, haces todo eso y además, te preguntas qué asume la especificación sin decirlo, qué permite la implementación sin haberlo pedido, y qué ocurre cuando el sistema recibe lo que nadie esperaba que recibiría.

En el ejemplo del campo numérico, nadie había pensado en los negativos porque el contexto de negocio los hacía absurdos. Un factor de precio negativo no tiene sentido. Pero el código no sabe de contexto de negocio: sabe de tipos de datos. Y un campo de tipo decimal acepta negativos por defecto, a menos que alguien lo prohíba explícitamente. Nadie lo había hecho; nadie había pensado en ello; nadie asumió que los usuarios podrían introducir valores negativos.

La mentalidad adversarial consiste en mantener simultáneamente dos preguntas: ¿funciona esto como se ha pedido? y ¿qué puede salir mal que nadie ha mencionado?

Por qué la segunda pregunta es la más importante

El happy path es la parte más segura del software. La ha probado el desarrollador mientras lo construía. La ha validado el Product Manager antes de cerrarlo. La ha verificado QA en cada iteración. Si algo va a escaparse, no va a escaparse ahí.

Los bugs que llegan a producción viven en los límites: en los valores que nadie ha probado durante el desarrollo, en las combinaciones que nadie ha imaginado, en las restricciones que todo el mundo ha asumido pero nadie ha escrito…

Y hay un patrón muy concreto que se repite: la falta de validación explícita. Cuando una especificación describe un campo sin decir qué valores no acepta, se convierte en una asunción. Todos asumen que nadie pondría un valor absurdo. Nadie se pregunta si el sistema lo impedirá, pero el sistema no lo impide.

La mentalidad adversarial convierte esa asunción implícita en una pregunta explícita. Y las preguntas explícitas, formuladas en el momento adecuado, cuestan minutos. El mismo defecto en producción puede costar días, datos comprometidos y la confianza de un usuario que ha fijado un contrato con un precio negativo porque el sistema se lo ha permitido.

Cómo funciona en la práctica

No requiere herramientas especiales ni un proceso diferente. Requiere un cambio en el punto de partida. Cuando recibes una funcionalidad para probar, antes de ejecutar ningún caso, hazte estas preguntas:

  • Sobre los datos: ¿Qué tipo de campo es? ¿Qué permite ese tipo por defecto que el negocio no necesita? ¿Hay valores límite que no están especificados: negativos, ceros, decimales, letras en campos numéricos, textos muy largos, fechas en pasado? ¿Qué pasa si el campo va vacío?
  • Sobre las asunciones: ¿Qué da por hecho la especificación sin decirlo? ¿Qué flujo asume que el usuario seguirá? ¿Qué ocurre si el usuario no lo sigue?
  • Sobre los efectos: ¿Esta funcionalidad toca algo más? ¿Qué módulos, registros o servicios dependen de este dato? ¿Si el valor es incorrecto en el origen, qué afectación tiene en el otro extremo?
  • Sobre el sad path: Cuando algo falla, ¿el sistema lo impide? ¿Lo avisa? ¿Lo sabe el usuario? ¿Hay una diferencia entre lo que el mensaje de error dice y lo que el sistema hace realmente? ¿Se puede ignorar el aviso y continuar de todas formas?

Ninguna de estas preguntas requiere tener el código delante. La mayoría se pueden responder con la especificación en la mano y un poco de escepticismo sano.

El momento en que más valor tiene

La mentalidad adversarial es más valiosa antes de ejecutar la primera prueba. Cuando todavía estás leyendo la especificación, formulando preguntas o diseñando los casos de prueba.

Un bug detectado en esa fase no llega al entorno de pruebas, no genera un ticket, no requiere una corrección, no necesita redespliegue, una nueva revisión ni una regresión. Se resuelve con una conversación: “Si introduzco valores negativos, ¿lo impide el sistema?” Si la respuesta es negativa o nadie lo sabe responder, esa pregunta acaba de evitar que algo llegue a producción.

Eso es lo que hace esta mentalidad especialmente potente: no es solo una forma de encontrar defectos. Es una forma de prevenir que el equipo de desarrollo los introduzca.

La controversia

Hay quien dice que esto es desconfianza sistemática, que ralentiza el proceso, que genera ruido con preguntas sobre casos que nunca van a ocurrir… Es una objeción razonable si el escepticismo se convierte en parálisis. Si cada campo genera diez preguntas y cada respuesta genera otras diez. Eso no es mentalidad adversarial: es ansiedad en estado puro.

La diferencia está en el criterio: no todo merece el mismo nivel de escrutinio. Un campo de texto libre en un formulario de comentarios y un campo numérico en un cálculo de contrato no tienen el mismo riesgo para negocio. La mentalidad adversarial no dice “desconfía de todo por igual”, dice “identifica dónde el coste de fallar es alto y sé especialmente difícil de convencer ahí”.

Un precio mal calculado en un contrato tiene consecuencias reales: económicas, legales y de confianza. Una descripción con un carácter extra, probablemente no. Aplica el escepticismo donde el impacto justifica el esfuerzo.

Lo que se escapa cuando no se piensa así

Hay una ilusión cómoda en el testing convencional: si los criterios de aceptación superan las pruebas, el software funciona. Es una ilusión porque los criterios de aceptación describen lo que alguien se imaginó que podría pasar. No describen lo que un usuario real, con datos reales, en un mal día, va a intentar hacer con el sistema.

La mentalidad adversarial no garantiza cobertura total. Nadie puede garantizarla. Lo que garantiza es una postura diferente frente al software: no estás aquí para confirmar que funciona. Estás aquí para encontrar lo que puede fallar antes de que lo encuentre alguien a quien le va a salir caro.


El happy path es donde el software es bonito. Los límites son donde el software se gana —o pierde— la confianza. Y los límites no se documentan solos: alguien tiene que hacerse la pregunta incómoda antes de que el usuario se convierta en el primero en encontrar la respuesta.

Piensa mal y acertarás (casi siempre).