~/pcn $ iniciando_

programaConNosotros

Iniciar sesiónCrear cuenta
  • programaConNosotrosprogramaConNosotrosComunidad · desde 2020
  • Inicio
  • Feed
Actividades
  • Eventos
  • Conversaciones
  • Foro
  • Consejos
  • Charlas
  • Podcast
  • Desarrolloaquí
  • Proyectos
Recursos
  • Cursos
  • Lectura
  • Videos
  • Especialidades
  • Herramientas
  • Entrevistas
Comunidad
  • Historia
  • Miembros
  • Logros
  • Galería
  • Setups
  • Partners
  • Changelog
  • Métricas
SoporteFeedback
  • iniciarSesion();Crear cuenta

~/desarrollo/calidad

quality engineering · 4660 casos de prueba

## Cómo probamos el sitio

Este sitio lo usa una comunidad real: gente que se inscribe a eventos con cupo, sube fotos, deja su contraseña. Por eso lo tratamos como software serio: 610 archivos de tests automatizados con 4533 casos en tres velocidades. 3675 tests unitarios y de componentes corren antes de cada push en segundos; 512 tests de integración corren las server actions contra un Postgres real; y una regresión e2e de 346 tests recorre el sitio en un navegador una vez por semana, automatizando 119 de los 127 casos manuales. Los tests no corren en CI: es una decisión para que el pipeline de deploy siga siendo rápido. Todo está acá abajo, con el link al código.

  1. 01 pre-commit$ pnpm exec lint-stagedHusky corre lint-staged, que formatea con Prettier solo los archivos que cambiaste (js, ts, tsx, json, css, md). Nadie commitea código sin formatear.
  2. 02 pre-push$ pnpm lint && pnpm format:check && pnpm test && pnpm buildESLint (que además prohíbe armar SQL a mano), el chequeo de formato, toda la suite unitaria y de componentes de Jest (incluidos los guardas de seguridad: SQL injection y chequeo de permisos en cada server action) y el build de producción, que chequea los tipos. Si algo falla, el push no sale.
  3. 03 integración$ pnpm test:dbAl tocar queries, el schema o server actions: corre las actions contra un Postgres real en una base descartable con todas las migraciones. Restricciones únicas, cascadas, transacciones, carreras por el último lugar de un evento y payloads de SQL injection.
  4. 04 pull request$ pnpm screenshot /ruta && pnpm screenshot:publishCada cambio entra por una PR hacia testing que revisa otra persona. Si toca la UI, lleva capturas de las rutas afectadas tomadas con Playwright (Chromium headless) y publicadas en la branch huérfana pr-screenshots.
  5. 05 regresión semanal$ pnpm test:e2eUna vez por semana y antes de un release grande: recrea una base con datos de prueba, compila el sitio en modo producción y lo recorre con Playwright (desktop y mobile), con un test por caso manual automatizado y una pasada por todas las rutas públicas buscando errores y violaciones de CSP.
  6. 06 deploy$ pnpm prisma migrate deploy && kamal deployEl push a main dispara GitHub Actions: instala con el lockfile congelado (--frozen-lockfile), aplica las migraciones pendientes y despliega con Kamal, que solo pasa el tráfico a la versión nueva cuando responde el health check de /up. Los tests no corren en CI, a propósito: corren antes, en cada máquina.
  7. 07 producción$ /monitoreo · notificacionesLos errores del servidor y del cliente quedan en ErrorLog y se revisan desde /monitoreo. Un error nuevo del servidor o un posible ataque de fuerza bruta (alguien que llega al límite de login o de códigos) les llega a los admins como notificación.

## La suite automatizada por capa

La mayoría de los tests están en la base de la pirámide: rápidos, sin red ni base de datos, y corren en cada push. Arriba, menos tests pero más reales: integración contra Postgres y e2e en un navegador. Cada caso automatizado del repositorio de abajo es uno de estos tests.

e2e

346 tests · 28 archivos

navegador real con Playwright contra la app corriendo

integración

512 tests · 36 archivos

server actions y queries contra un Postgres real (pnpm test:db)

route handler

48 tests · 14 archivos

endpoints de src/app/api con Request y Response reales

server action

665 tests · 99 archivos

src/actions con Prisma, cookies y headers mockeados

componente

1890 tests · 292 archivos

componentes de React en jsdom con Testing Library

unit

1072 tests · 141 archivos

funciones puras de src/lib, schemas y contenido

## Cobertura

Qué parte del código ejecutan los tests unitarios y de componentes (pnpm test:coverage). La integración y la regresión e2e cubren el mismo código desde afuera y no suman acá. Medido el 9 de octubre de 2026; se actualiza con pnpm qa:cases.

src/lib

lógica compartida, seguridad, cache, S3 · 93 archivos

líneas97.8%

sentencias96.7%

funciones96.4%

ramas92.3%

src/actions

server actions · 112 archivos

líneas96.6%

sentencias95.5%

funciones96.5%

ramas88.5%

src/schemas

validaciones con zod · 13 archivos

líneas99.6%

sentencias98.6%

funciones100%

ramas96.7%

src/hooks

hooks de React · 2 archivos

líneas100%

sentencias98.5%

funciones100%

ramas94.4%

src/components

componentes · 424 archivos

líneas97.6%

sentencias96.9%

funciones95.6%

ramas93%

src/app

páginas, layouts y route handlers · 328 archivos

líneas98.3%

sentencias97%

funciones97.7%

ramas93.4%

total: 97.7% de líneas · 92.5% de ramas · 96.3% de funciones

## Regresión e2e semanal

Una vez por semana (y antes de un release grande) corremos pnpm test:e2e: recrea una base con datos de prueba (un usuario por rol, eventos con y sin cupo, charlas, consejos), compila el sitio en modo producción y lo recorre con Playwright en Chromium desktop y en un Pixel 7. Son 346 tests en 28 archivos: cada caso manual que automatizan lleva su id en el nombre y abajo aparece marcado como e2e. Lo que no se puede automatizar (instalar la PWA, mails reales, subir a S3) sigue siendo manual.

casos manuales automatizados
119/127
tests e2e
346
integración (Postgres)
512
pre-push
3675

## Herramientas

Jest 30
El runner de unit, componentes e integración, con next/jest (el compilador SWC de Next.js). Dos proyectos: node para *.test.ts (lib, schemas, server actions, route handlers) y jsdom para *.test.tsx (componentes). La integración usa su propia config. jest.config.mjs ↗
Testing Library
@testing-library/react y user-event renderizan los componentes en jsdom y los usan como una persona: por rol, label y texto, tipeando y haciendo click. jest.setup.dom.ts simula el router de Next y las APIs del navegador que jsdom no tiene. jest.setup.dom.ts ↗
jest-mock-extended
En la suite unitaria, jest.setup.ts reemplaza el cliente de Prisma por un mockDeep tipado y lo resetea antes de cada test: las server actions se prueban sin base y TypeScript avisa si un mock no coincide con el modelo. jest.setup.ts ↗
Postgres de integración
pnpm test:db crea una base descartable por corrida al lado de la de desarrollo (solo en un Postgres local), aplica las migraciones, corre las actions con Prisma de verdad y sesiones reales por rol, y la borra al terminar. jest.db.config.mjs ↗
Playwright
La regresión e2e: una base propia sembrada (un usuario por rol), un build de producción en su propio puerto, login una vez por rol guardado como storage state, una IP distinta por test para que no se crucen los rate limits, Desktop Chrome y Pixel 7. También toma las capturas de las PRs. playwright.config.ts ↗
Cobertura
pnpm test:coverage mide líneas, ramas y funciones; pnpm qa:cases guarda el resumen por carpeta que se muestra en esta página. scripts/generate-automated-cases.mjs ↗
Helpers de test
src/test trae mockCookies(), mockHeaders() y prismaMock para la suite unitaria, createUser() y actAs() para la de integración (crea la sesión en la base), y builders de eventos, charlas y galería para los componentes. src/test/db/fixtures.ts ↗
TypeScript strict
strict y strictNullChecks activados en tsconfig.json: null, undefined y los tipos de Prisma se chequean en todo el código. El build falla con cualquier error de tipos. tsconfig.json ↗
Zod
Schemas en src/schemas que validan lo mismo en el formulario (react-hook-form + zodResolver) y en la server action, con los mensajes en español. Zod descarta los campos que no están en el schema, así nadie puede mandar role: ADMIN en un formulario de perfil. src/schemas/profile-schema.ts ↗
Prisma
Cliente tipado generado desde el schema, restricciones únicas compuestas en la base (no se puede inscribir dos veces a la misma persona), datos sensibles omitidos por defecto y migraciones SQL versionadas. prisma/schema.prisma ↗
ESLint 9 + Prettier
Flat config con eslint-config-next/core-web-vitals y reglas propias que prohíben $queryRawUnsafe, Prisma.raw y drivers de base que no sean Prisma; Prettier 3 con el plugin que ordena las clases de Tailwind. eslint.config.mjs ↗
Husky + lint-staged
Los hooks de git que hacen de CI local: nada llega al repo sin pasar los checks. .husky/pre-push ↗
Dependabot
Abre PRs los lunes para dependencias con vulnerabilidades conocidas o desactualizadas; pnpm.overrides fuerza versiones parcheadas de dependencias transitivas. .github/dependabot.yml ↗
Bases aisladas por worktree
Cada worktree de git tiene su propia base de Postgres (scripts/setup-worktree-db.sh) y su URL con portless, así se prueban varias branches en paralelo sin pisarse datos ni puertos. scripts/setup-worktree-db.sh ↗
MailHog
En desarrollo los emails no salen a internet: docker-compose levanta MailHog y se leen en localhost:18025. En la suite e2e los mails no se mandan (jsonTransport) y los tests leen los códigos de la base. docker-compose.yml ↗

## Técnicas

Tests colocalizados
Cada test vive al lado del código que prueba (create-event.ts → create-event.test.ts y create-event.db.test.ts). Si movés o borrás el módulo, el test va con él.
Test doubles
En la suite unitaria, Prisma, cookies(), headers(), revalidatePath, S3, el envío de emails y fetch se reemplazan por mocks: rápidos y deterministas. La integración usa los reales.
Matriz de permisos
Toda server action se prueba primero por lo que tiene que rechazar: sin sesión, sesión vencida, usuario que no es el autor, que no es organizador, que no es admin. Un test lee el AST de cada action y falla si alguna no valida la sesión o los permisos sin estar declarada pública. src/lib/server-action-auth.test.ts ↗
SQL injection
Un test recorre el AST de todo src/ y falla ante cualquier forma de armar SQL a mano; otro manda payloads clásicos (tautologías, DROP TABLE, UNION, pg_sleep) por cada formulario contra Postgres real y comprueba que se guardan como texto, que nadie entra y que las tablas siguen intactas. src/test/sql-injection.db.test.ts ↗
Concurrencia
La integración dispara requests a la vez: varias personas por el último lugar de un evento, la misma persona inscribiéndose dos veces, un doble click al convertir una propuesta en charla, intentos de código en paralelo. src/actions/events/registration.db.test.ts ↗
Testing negativo y de bordes
Particiones de equivalencia y valores límite sobre los schemas: contenido vacío, un carácter de más, fechas en el pasado o al revés, cupo lleno exacto, códigos vencidos o ya usados. src/schemas/event-schema.test.ts ↗
Tests parametrizados
it.each recorre tablas de casos (direcciones IP privadas, redirecciones peligrosas, payloads de inyección, cada track de entrevistas) con un solo cuerpo de test. src/lib/safe-fetch.test.ts ↗
Tiempo controlado
jest.useFakeTimers y page.clock de Playwright congelan el reloj para probar ventanas del rate limit, cuentas regresivas de los códigos y qué eventos son "próximos". src/lib/rate-limit.test.ts ↗
Tests de seguridad
SSRF con servidores HTTP reales (IPs internas, redirects, DNS rebinding), CSP con nonce por request, open redirect después del login, mass assignment en el perfil, timing del login, URLs firmadas de la galería y path traversal en las descargas. src/lib/safe-fetch.test.ts ↗
Bugs fijados con tests
Un bug encontrado se escribe primero como test del comportamiento correcto (it.failing / test.fail) y se arregla después, dando vuelta el test. Así esta suite encontró y cerró, entre otros, un escalamiento a admin desde el perfil, inscripciones a eventos terminados y respuestas que caían en otro consejo.
Binarios reales
El procesamiento de fotos se prueba con imágenes generadas con sharp en el momento: que achique, que nunca agrande, que respete la rotación EXIF y que salga en webp. src/lib/photo-processing.test.ts ↗
Regresión de rutas
Un spec e2e recorre todas las rutas públicas y falla con un status distinto de 200, una página sin título, un error en la consola o una violación de la CSP. tests/e2e/plataforma-navegacion.spec.ts ↗
Revisión visual
Las capturas de cada ruta afectada van en la PR para que la revisión no dependa de levantar el proyecto.
Testing manual exploratorio
Lo que la regresión e2e no automatiza (instalar la PWA, mails reales, subir a S3, accesibilidad con lector de pantalla) se prueba a mano siguiendo los casos de este repositorio.

## Lo que falta (planeado, todavía no está)

Ser honestos con lo que no hay también es parte de la calidad. Esto no existe todavía en el repo; es lo próximo que sumaríamos. Si te interesa, es un buen lugar para contribuir.

[ ] Accesibilidad automatizada
Sumar @axe-core/playwright a la regresión e2e para detectar contraste, labels y roles faltantes en cada ruta.
[ ] Regresión visual
Comparar capturas de cada ruta contra las de la semana anterior y marcar las diferencias en píxeles.
[ ] Mutation testing
Stryker sobre src/lib y src/actions para medir si los tests detectan cambios en el código, no solo si lo ejecutan.
[ ] Regresión programada
Que la corrida semanal de pnpm test:e2e se dispare sola en una máquina con la base local y deje el reporte de Playwright publicado.

## Repositorio de casos de prueba

Todo lo que se prueba en el sitio, área por área. Los casos manuales describen cada flujo paso a paso; los marcados e2e ya los corre la regresión semanal. Los automatizados salen directo de Jest y Playwright, con el archivo y el comando para correr cada uno. Podés linkear un caso con #TC-GAL-001.

4660

casos en total

127

manuales

4533

automatizados

849

prioridad alta

### cobertura por área · tocá un área para filtrar

4660/4660 casos

$ pnpm qa:cases # regenera los casos automatizados · última actualización: 9 de octubre de 2026

$ ¿Encontraste algo que no está cubierto? Sumá el caso o el test en una PR.

~/desarrollo#contribuir →