Herramientas y Guías 3 minutos de lectura

Testing para humanos: qué probar, cómo y sin obsesionarte

Introducción

El testing suele fracasar por dos extremos que se parecen más de lo que parece: equipos que no prueban nada y equipos que lo prueban todo acaban en el mismo sitio: pipelines lentos, tests frágiles y desconfianza.

El problema no es “falta de herramientas”. El problema es estrategia. Testing no es una disciplina aislada; es una propiedad emergente del diseño, la arquitectura y la forma de trabajar del equipo.

Este post no va de fanatismos ni de “subir cobertura”. Va de lo que importa: gestionar riesgo, reducir incertidumbre y poder evolucionar sin miedo.

Qué es testing en serio: gestión de riesgo (no “control de calidad”)

El error más común es pensar que los tests existen para “garantizar que no haya bugs”. Eso es imposible. El objetivo real del testing es:

  • detectar fallos antes de que impacten en producción,
  • reducir incertidumbre cuando cambias código,
  • permitir evolución sin miedo (refactor y cambios de requisitos),
  • convertir errores en aprendizaje: menos incendios, más control.

Un sistema bien testeado no es el que nunca falla. Es el que falla de forma controlada, lo detecta pronto y se recupera rápido.

Mini guía en 5 minutos: por dónde empezar sin bloquearte

  1. Identifica riesgos: ¿qué parte del sistema te da más miedo cambiar?
  2. Define 3 flujos críticos (los que no te puedes permitir romper).
  3. Testea reglas (unit) y fronteras (integración) antes que “pantallas”.
  4. Haz E2E selectivo: pocos, estables, y para lo que realmente importa.
  5. Mete el testing en el pipeline: si no corre en CI, no existe.

Teoría base de testing (lo mínimo que un equipo serio debería dominar)

1) Partición de equivalencia

No puedes probar infinitos valores. Agrupa entradas en “clases” que se comportan igual y prueba un representante por clase. Reducen casos sin perder cobertura de comportamiento.

2) Análisis de valores límite

Los fallos suelen vivir en los bordes: 0, 1, máximo, mínimo, justo antes y justo después. Si tu sistema valida, calcula o aplica límites, los bordes son oro.

3) Tablas de decisión

Cuando hay reglas con múltiples condiciones (“si A y B pero no C…”), una tabla de decisión evita casos olvidados. Es una herramienta infravalorada para negocio.

4) Pruebas de transición de estados

Si tu dominio tiene estados (pedido: nuevo → pagado → enviado → devuelto), aquí es donde se rompen sistemas. Valida transiciones válidas, inválidas e invariantes.

5) Exploratory testing (sí, también es profesional)

No todo es automatizable. Exploratorio no significa improvisado: significa explorar con hipótesis, observación y aprendizaje, especialmente útil en UI, edge cases y UX real.

Tipos de tests y qué problema resuelve cada uno

Tipo Qué valida Cuándo es clave Riesgo típico
Unitarios Reglas e invariantes Dominio con lógica real Testear implementación en vez de comportamiento
Integración Fronteras: DB, colas, serialización, transacciones, IO Cuando “en prod falla pero en unit pasa” Flakiness si el entorno no es reproducible
Contrato Compatibilidad entre servicios o clientes Equipos separados / APIs públicas Romper contratos sin darse cuenta
E2E Flujos críticos “como usuario” 3–10 flujos clave del negocio Caros y frágiles si se abusa
Smoke Que lo esencial vive tras un despliegue Post-deploy Confundirlo con E2E

Quién debe hacer qué: roles y responsabilidad (sin guerras Dev vs QA)

El salto de madurez no es técnico, es cultural: calidad es responsabilidad compartida. QA no es “policía” y Dev no es “el que corre”. Un reparto sano es:

Rol Responsabilidad principal Qué debería automatizar
Desarrollo Reglas de negocio, testabilidad del diseño Unit + integración básica + contratos de API
QA Estrategia, cobertura de riesgo, exploratorio E2E selectivo + regresión crítica + casos borde
Producto Definir criticidad e impacto del fallo Criterios de aceptación claros, DoD con calidad
DevOps/SRE Pipeline, entornos, observabilidad, gates Smoke post-deploy + gates de calidad/seguridad

En qué fase se hacen los tests: del commit a producción

Una estrategia básica y profesional organiza el testing por coste y por momento:

  • Antes del commit: unit rápidos (y linters/formatters).
  • En Pull Request: unit + integración + calidad (gates).
  • En staging: smoke + E2E selectivo + pruebas exploratorias.
  • Post-deploy: smoke controlado + monitorización (métricas/logs) para detectar regresión.

Pirámide, diamante y “honeycomb”: no es dogma, es coste

La pirámide (muchos unit, menos integración, pocos E2E) existe por una razón económica: los tests lentos y frágiles cuestan más de lo que aportan si se convierten en mayoría.

  • Pirámide: ideal cuando el dominio es fuerte y testeable.
  • Diamante: demasiada integración porque el diseño no permite unit (señal de deuda).
  • Honeycomb: probar fronteras (integración/contratos) sin convertir E2E en religión.

La regla de oro: testear comportamiento, no implementación

Los tests que sobreviven a refactors son los que verifican decisiones: entradas → comportamiento → salidas/efectos observables.

Los tests que mueren con cada cambio suelen estar acoplados a detalles internos. Eso genera la peor dinámica: el equipo empieza a odiar el testing porque lo percibe como freno.

Flaky tests: el veneno silencioso

Un test que falla de forma intermitente destruye la confianza. Un test flaky es peor que no tener test: entrena al equipo a ignorar el pipeline.

Causas típicas:

  • dependencia de tiempo (sleep, timeouts mal puestos),
  • orden no determinista (datos compartidos),
  • entornos inestables,
  • UI E2E con selectores frágiles.

Política sana: un test flaky se corrige o se elimina. No se tolera.

Cómo implantar testing según tamaño de empresa (plan realista)

Empresa pequeña (1–3 devs, sin QA)

  • Unit para reglas críticas.
  • Integración mínima en fronteras (DB/API).
  • 2–3 smoke tests manuales por release.
  • Pipeline: build + unit + integración mínima (rápido).

Pyme con producto propio (equipo 4–10, con releases frecuentes)

  • Unit + integración estructurados.
  • Contratos de API si hay integraciones externas.
  • E2E selectivo (3–10 flujos críticos).
  • QA exploratorio planificado y basado en riesgos.

Equipo grande / múltiples servicios

  • Contract testing obligatorio.
  • E2E mínimo y estable (si es masivo, el pipeline muere).
  • Staging serio + smoke post-deploy + observabilidad.
  • Quality gates y métricas de riesgo (no solo cobertura).

Cómo introducir testing en un proyecto legacy (sin reescritura)

En legacy, el objetivo no es pureza: es ganar margen de maniobra.

  1. Characterization tests: captura el comportamiento actual antes de tocar.
  2. Fronteras primero: DB, serialización, integraciones y reglas críticas.
  3. Refactor incremental: pequeñas mejoras con red de seguridad.
  4. Deuda visible: lista de zonas de riesgo y plan para reducirlas.

Métricas útiles (mejor que “cobertura por ego”)

  • Tiempo de feedback del pipeline (minutos, no horas).
  • Ratio de flaky tests (debería tender a 0).
  • MTTR cuando hay fallo en producción.
  • % flujos críticos cubiertos (mejor que cobertura global).
  • Defect escape rate: bugs que llegan a prod.

Checklist final (para saber si tu estrategia es sana)

  1. ¿Los tests rápidos dan feedback en minutos?
  2. ¿El pipeline es confiable (no flaky) y el equipo lo respeta?
  3. ¿Las reglas de negocio críticas están protegidas?
  4. ¿Las fronteras (DB/APIs/colas) están cubiertas con integración o contratos?
  5. ¿E2E es selectivo y estable?
  6. ¿Dev, QA y producto colaboran en riesgos y criterios de aceptación?

Conclusión

Testing no es un ritual ni una métrica: es ingeniería aplicada a un objetivo simple: reducir miedo al cambio.

La diferencia entre un equipo maduro y uno que vive en incendios no es “si tiene tests”: es si tiene una estrategia que combina teoría útil, colaboración y automatización.

En Gondor defendemos testing como parte de la arquitectura y del proceso, no como una obligación decorativa.

¿Tu empresa necesita incorporar, impulsar o revisar procesos de QA?

En Gondor Solutions ayudamos a pymes a ir un paso más allá, reducir complejidad y construir sistemas que funcionan en la vida real.

Hablemos