Skip to content

Instantly share code, notes, and snippets.

@serrodcal
Last active March 30, 2026 12:56
Show Gist options
  • Select an option

  • Save serrodcal/dedfd896c503f5d02889c2c423749dbe to your computer and use it in GitHub Desktop.

Select an option

Save serrodcal/dedfd896c503f5d02889c2c423749dbe to your computer and use it in GitHub Desktop.

Aquí tienes un documento-resumen completo (tipo “chuleta”) con todo lo que hemos hablado junto: diferencias, cuándo aplicar cada tipo de test, ejemplos sencillos y cómo encaja con la pirámide de testing. Guárdalo y úsalo como referencia.


📌 Guía rápida de tipos de testing (con pirámide) — Resumen definitivo

1) La idea clave: Pirámide de testing (por qué existe)

La pirámide te dice cómo repartir esfuerzos:

  • Base (muchos, rápidos, baratos): pruebas pequeñas (unitarias) + análisis estático
  • Medio (algunos, realistas): integración, contratos, API
  • Cima (pocos, caros, frágiles): end-to-end / UI

Regla de oro:

Cuanto más arriba, más realista… pero más lento y frágil.
Cuanto más abajo, menos realista… pero más rápido y estable.


2) Tipos “esenciales” (los que preguntaste al principio)

2.1 ✅ Test unitario (Unit test)

Qué es: prueba una función/clase aislada, sin red, sin BBDD, sin filesystem.
Cuándo aplicar: siempre que haya lógica: validaciones, reglas de negocio, cálculos, transformaciones.
Ejemplo tonto: probar sumar(2,3)=5.

Idea simple: “Pruebo una pieza de LEGO suelta”.


2.2 ✅ Smoke test

Qué es: prueba mínima para saber si el sistema “está vivo” (arranca y no explota).
Cuándo aplicar: después de desplegar, al levantar entornos, como verificación rápida post-deploy.
Ejemplo típico:

  • /health responde 200
  • login básico funciona
  • endpoint principal no da 500

Idea simple: “Humo = si hay fuego, me entero rápido”.


2.3 ✅ Mutation test (Pruebas de mutación)

Qué es: no prueba el sistema; prueba la calidad de tus tests.
La herramienta introduce pequeños “bugs” en el código (mutaciones) y mira si tus tests los detectan.

  • Si al mutar el código los tests fallan → bien (tus tests lo pillarían en producción)
  • Si al mutar el código los tests siguen pasando → mal (tus tests son débiles)

Cuándo aplicar:

  • lógica crítica donde quieres mucha confianza
  • cuando ya tienes unit tests pero quieres medir si “muerden de verdad”
  • para mejorar cobertura “útil”, no solo líneas ejecutadas

Ejemplo tonto:
Código real: edad >= 18
Mutación: edad > 18
Si no tienes test para edad=18, la mutación “sobrevive” → te falta ese caso.

Idea simple: “Pongo trampas al código para ver si mis tests las detectan”.


3) Pirámide: tipos por “nivel”

3.1 Base (rápidos y baratos)

A) Unit tests (unitarios)

  • Lógica pura, reglas, validaciones
  • Muchísimos, rápidos, estables

B) Component / Module tests (componente)

Qué son: prueban un módulo completo, pero con dependencias simuladas (mocks).
Cuándo: cuando un servicio coordina varias piezas internas.

C) Property-based testing (basado en propiedades)

Qué es: defines una regla que siempre debe cumplirse y el framework genera muchos casos.
Cuándo: lógica de transformaciones, parsers, validaciones. Ejemplo: abs(n) >= 0 para cualquier n.

D) Static testing (sin ejecutar)

  • Lint/Format: estilo, imports, errores obvios.
  • SAST/Static analysis: patrones de vulnerabilidad y bugs (muy útil en CI).

3.2 Medio (integración controlada)

A) Integration tests (integración)

Qué son: pruebas con “algo real”: BBDD, colas, filesystem, cache.
Cuándo: para validar mapeos, SQL, serialización, configuración real.

B) Contract tests (contratos)

Qué son: garantizan que servicios se entienden (API/JSON/gRPC/eventos).
Cuándo: microservicios (evita romper consumidores).
Idea: “hablamos el mismo idioma sin levantar todo el sistema”.

C) API tests

Qué son: pruebas directas a endpoints (HTTP/gRPC), sin UI.
Cuándo: cuando la API es el corazón del sistema.

D) DB migration tests

Qué son: verifican que migraciones (Flyway/Liquibase) aplican bien con datos realistas.
Cuándo: cada cambio de esquema o release.


3.3 Cima (pocos, caros y realistas)

A) E2E (end-to-end)

Qué son: prueban el flujo completo como un usuario o sistema externo.
Cuándo: solo flujos críticos (pocos): login → home → acción clave.
Contras: lentos y frágiles.

B) UI tests

Qué son: automatizan navegador/app (Playwright/Selenium).
Cuándo: cuando la UI es crítica o legalmente exigente.

C) Acceptance / UAT

Qué es: validación de requisitos por negocio (manual o automatizada).
Cuándo: antes de release / hitos.


4) Tipos “horizontales” (por objetivo, no por nivel)

4.1 Sanity vs Regression (diferencia rápida)

  • Sanity: tras un cambio pequeño, compruebas “lo tocado” y lo esencial relacionado.
  • Regression: suite para asegurar que nada que funcionaba antes se ha roto.

4.2 Exploratory testing

Qué es: pruebas manuales “inteligentes” explorando casos raros.
Cuándo: features nuevas, bugs raros, incertidumbre alta.

4.3 Security testing (muy importante)

  • DAST: pruebas dinámicas contra el sistema corriendo.
  • Pentest: más profundo (manual + herramientas).
  • Fuzzing: entradas aleatorias/maliciosas para romper parsers/APIs.

4.4 Resilience / Chaos

Qué es: provocas fallos (matar pods, cortar red, latencia) para validar resiliencia.
Cuándo: sistemas críticos / SRE.

4.5 Compatibility / i18n / a11y

  • Compatibilidad: navegadores, móviles, OS, versiones.
  • i18n: idiomas, formatos fecha/moneda, textos largos.
  • Accesibilidad: teclado, contraste, lectores de pantalla.

4.6 Backup/Restore & DR

Qué es: comprobar que puedes restaurar datos y servicios.
Cuándo: siempre que haya datos críticos / auditorías.


5) Rendimiento: carga vs volumen (lo que faltaba)

5.1 ✅ Load test (prueba de carga)

Pregunta: “¿Qué pasa si entran muchos usuarios a la vez?”
Se centra en concurrencia / tráfico: usuarios simultáneos, RPS.

Ejemplo simple:

  • 500 usuarios concurrentes durante 10–30 min
  • medir latencia p95, errores 5xx, CPU/RAM, pool de conexiones

5.2 ✅ Volume test (prueba de volumen)

Pregunta: “¿Qué pasa si tengo MUCHÍSIMOS datos?”
Se centra en tamaño del dataset: tablas enormes, millones de registros, colas gigantes.

Ejemplo simple:

  • poblar BBDD con 200M registros
  • probar un endpoint con poca concurrencia
  • medir tiempo de query, IO, locks, uso de índices

5.3 Otros “vecinos” de performance (muy útiles)

  • Stress test: subes más allá de lo esperado hasta que rompe → encuentras límite.
  • Spike test: pico repentino (50 → 1000 usuarios en 10s) → autoscaling/rate-limit.
  • Soak/Endurance: muchas horas → memory leaks, degradación, colas acumuladas.
  • Capacity/Scalability: cuánto aguanta con X recursos; escala lineal o no.

Idea simple de performance:

  • Carga = “mucha gente”
  • Volumen = “muchos datos”
  • Soak = “mucho tiempo”
  • Spike = “picos bruscos”
  • Stress = “hasta romper”

6) Cuándo usar qué (guía “modo torpe”)

Si quieres validar lógica:

✅ Unit tests
✅ Property-based
✅ Mutation (para medir calidad de los unit)

Si quieres validar “habla con el mundo real”:

✅ Integration tests
✅ DB migration tests
✅ Contract tests (si hay microservicios)
✅ API tests

Si quieres validar “como lo usa el usuario”:

✅ E2E / UI
✅ Acceptance/UAT

Si quieres saber si “está vivo tras deploy”:

✅ Smoke tests

Si quieres evitar “rompí algo que funcionaba”:

✅ Regression tests (+ sanity para cambios pequeños)

Si tu miedo es rendimiento:

✅ Load (mucha gente)
✅ Volume (muchos datos)
✅ Soak (mucho tiempo)
✅ Spike (picos)
✅ Stress (límite)


7) Ejemplo único (mismo sistema visto por muchos tests)

Imagina un sistema con:

  • POST /login
  • GET /dashboard (consulta BBDD)

Unit: validar password/roles
Integration: repositorio guarda/lee usuario real en BBDD
Contract: /login siempre devuelve {token, expiresIn}
API test: POST /login con credenciales válidas → 200
E2E/UI: usuario entra → login → ve dashboard
Smoke: /health 200 + login básico
Regression: suite de endpoints clave
Mutation: cambian una comparación y miras si tus tests lo detectan
Load: 500 usuarios simultáneos en dashboard
Volume: 200M filas en movimientos, dashboard sigue respondiendo
Soak: 8h con carga moderada para detectar fugas


8) Recomendación práctica (cómo lo pondría en un pipeline)

Una receta muy usada y eficiente:

En cada PR (rápido)

  • Lint + SAST
  • Unit tests
  • Algún component test
  • Un puñado de integration tests rápidos (si caben)

Nightly / diario

  • Integration tests más amplios
  • Contract tests
  • API regression suite

Post-deploy (siempre)

  • Smoke tests (2–5 minutos, súper básicos)

Semanal / por release

  • Load baseline (30–60 min)
  • Volume tests (dataset grande)
  • Soak (si el sistema es crítico)
  • DAST / security suites

9) Métricas mínimas para no volverte loco

Para load/stress/spike

  • latencia p50/p95/p99
  • throughput (RPS)
  • errores (5xx, timeouts)
  • CPU/RAM, GC (si Java), pool conexiones, colas

Para volumen

  • tiempos de query
  • IO disco / cache hit ratio
  • locks/contención
  • uso de índices y paginación

Si quieres, lo convierto en “plantilla corporativa”

Puedo:

  • adaptarlo a vuestro vocabulario (por ejemplo: PerfSmoke, Canary, EnvironmentPulse, RegressionAPI, etc.)
  • o hacerte una versión “1 página” ultra compacta para Confluence.

👉 Pregunta rápida: ¿lo quieres más orientado a backend/API (tipo microservicios) o también a UI web? Con eso lo ajusto para que te sirva al 100% en tu día a día.

Perfecto, vamos muy despacio y con un ejemplo súper sencillo, como si lo estuviéramos explicando en una pizarra 🙂


La historia base (el ejemplo)

Imagina esta función muy simple:

int sumar(int a, int b) {
    return a + b;
}

Y piensa en una aplicación que usa esta función (por ejemplo, una app de banca que suma importes).

A partir de aquí veremos:

  • Test unitario
  • Smoke test
  • Mutation test

1️⃣ Test unitario

👉 ¿Funciona correctamente ESTA pieza concreta de código?

📌 Qué es

Un test unitario prueba una función o método aislado, sin depender de nada más.

  • Es pequeño
  • Es rápido
  • Es preciso
  • Si falla, sabes exactamente dónde

📌 Cuándo se usa

  • Siempre que escribes lógica
  • Para asegurarte de que el código hace lo que dices que hace
  • En cada build / en local / en CI

📌 Ejemplo

@Test
void sumar_dosNumeros() {
    int resultado = sumar(2, 3);
    assertEquals(5, resultado);
}

✅ Si pasa → la función suma bien
❌ Si falla → hay un bug en esa función

🧠 Explicación “para torpes”

“Le doy 2 y 3.
Si no me devuelve 5, algo está mal.”


2️⃣ Smoke test

👉 ¿La aplicación arranca y no explota nada básico?

📌 Qué es

Un smoke test es una prueba muy superficial, para comprobar que:

  • La app arranca
  • Lo principal responde
  • No hay incendios 🔥

No revisa lógica fina, solo que lo mínimo funciona.

📌 Cuándo se usa

  • Justo después de desplegar
  • Antes de seguir probando cosas más complejas
  • En entornos: dev, pre, prod

💡 Viene de: “si enchufas y sale humo, algo va mal”

📌 Ejemplo

Para una API:

✅ El servidor arranca
✅ /health responde 200
✅ Login responde algo (aunque no verifiques todo)

O en pseudo-test:

@Test
void aplicacion_arranca() {
    Response response = call("/health");
    assertEquals(200, response.status);
}

🧠 Explicación “para torpes”

“No sé si suma bien.
Pero al menos arranca, responde y no se cae.”


3️⃣ Mutation test

👉 ¿Tus tests son lo bastante buenos como para detectar errores?

⚠️ Este es el más “raro” al principio.


📌 Qué es

Un mutation test NO prueba tu código,
prueba la calidad de tus tests.

👉 Lo que hace:

  1. Modifica tu código a propósito
  2. Hace un pequeño error
  3. Ejecuta los tests
  4. Mira si los tests lo detectan

📌 Ejemplo

Código original:

int sumar(int a, int b) {
    return a + b;
}

Mutación automática:

int sumar(int a, int b) {
    return a - b;   // ❌ ERROR INTRODUCIDO A PROPÓSITO
}

Ahora pasa tus tests unitarios.

  • ✅ Si el test falla → BUEN TEST
  • ❌ Si el test sigue pasando → TEST MALO

📌 Resultado típico

Mutation killed ✅  → el test detectó el error
Mutation survived ❌ → el test NO sirve

📌 Cuándo se usa

  • Para mejorar calidad de tests
  • En código crítico
  • No en cada build (es lento)
  • En pipelines avanzados

🧠 Explicación “para torpes”

“Voy a romper el código a escondidas.
Si tus tests no se dan cuenta…
tus tests son una mierda.”

(con cariño 😄)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment