8 min lectura • Guide 112 of 877
Creando Criterios de Aceptación Claros
Requerimientos vagos llevan a malentendidos, retrabajo y frustración. Los criterios de aceptación claros definen exactamente qué necesita ser verdad para que una tarea se considere completa. Las tareas en GitScrum con criterios de aceptación bien definidos se completan correctamente la primera vez.
Por Qué Importan los Criterios de Aceptación
| Sin Criterios Claros | Con Criterios Claros |
|---|---|
| "Pensé que querías decir..." | Entendimiento compartido |
| Retrabajo después de review | Correcto la primera vez |
| Scope creep | Límites claros |
| QA no sabe qué testear | Condiciones testeables |
| Ir y venir sin fin | Verificación rápida |
Formatos de Criterios de Aceptación
Formato Given-When-Then
GIVEN-WHEN-THEN (Sintaxis Gherkin)
══════════════════════════════════
FORMATO:
DADO [precondición/contexto]
CUANDO [acción/trigger]
ENTONCES [resultado esperado]
EJEMPLO: Login de Usuario
─────────────────────────────────────
DADO un usuario registrado en la página de login
CUANDO ingresa credenciales válidas
ENTONCES es redirigido al dashboard
Y ve un mensaje de bienvenida con su nombre
DADO un usuario en la página de login
CUANDO ingresa una contraseña inválida
ENTONCES ve un mensaje de error "Credenciales inválidas"
Y el campo de contraseña se limpia
Y el intento de login se registra
DADO un usuario que ya está logueado
CUANDO navega a la página de login
ENTONCES es redirigido al dashboard
─────────────────────────────────────
Formato Checklist
FORMATO CHECKLIST
═════════════════
EJEMPLO: Feature de Búsqueda
Criterios de Aceptación:
- [ ] Usuario puede ingresar términos de búsqueda en el campo
- [ ] Búsqueda se ejecuta cuando presiona Enter o click Buscar
- [ ] Resultados se muestran en menos de 2 segundos
- [ ] Resultados muestran título, extracto y fecha por cada match
- [ ] Mensaje "No se encontraron resultados" cuando no hay matches
- [ ] Mínimo 2 caracteres requeridos para buscar
- [ ] Términos de búsqueda se resaltan en resultados
- [ ] Usuario puede limpiar búsqueda y volver a vista default
- [ ] Búsqueda funciona en móvil (responsive)
- [ ] Historial de búsqueda no se guarda (privacidad)
Formato Basado en Reglas
FORMATO BASADO EN REGLAS
════════════════════════
EJEMPLO: Requisitos de Contraseña
Reglas:
1. Contraseña debe ser 8-64 caracteres
2. Debe contener al menos una letra mayúscula
3. Debe contener al menos una letra minúscula
4. Debe contener al menos un número
5. Debe contener al menos un carácter especial (!@#$%^&*)
6. No puede contener espacios
7. No puede coincidir con ninguna de las últimas 5 contraseñas
8. No puede contener el nombre de usuario
9. Medidor de fortaleza se actualiza en tiempo real
10. Mensajes de error explican qué regla falla
Escribiendo Criterios de Calidad
Ejemplos Buenos vs Malos
CALIDAD DE CRITERIOS DE ACEPTACIÓN
══════════════════════════════════
MALO (vago):
✗ "Usuario puede buscar"
✗ "Hacerlo rápido"
✗ "Manejar errores apropiadamente"
✗ "Debería funcionar en móvil"
✗ "Validar input"
BUENO (específico y testeable):
✓ "Usuario puede buscar ingresando texto y presionando Enter"
✓ "Resultados de búsqueda se muestran en 2 segundos para hasta 10,000 registros"
✓ "Email inválido muestra error: 'Por favor ingrese un email válido'"
✓ "Formulario es completamente funcional a 320px de ancho de viewport"
✓ "Campo email acepta solo formato de email válido (user@domain.ext)"
Áreas de Cobertura
QUÉ CUBRIR EN CRITERIOS DE ACEPTACIÓN
═════════════════════════════════════
HAPPY PATH:
├── Flujo exitoso normal
├── Comportamiento esperado del usuario
└── Caso de uso principal
EDGE CASES:
├── Estados vacíos
├── Valores límite
├── Inputs inusuales pero válidos
└── Acciones concurrentes
ESCENARIOS DE ERROR:
├── Input inválido
├── Fallos de red
├── Permiso denegado
├── Manejo de timeout
└── Errores de sistema
NO FUNCIONALES:
├── Requisitos de performance
├── Accesibilidad (nivel WCAG)
├── Soporte de browser/dispositivo
├── Requisitos de seguridad
└── Necesidades de localización
Template para Historias de Usuario
HISTORIA DE USUARIO CON CRITERIOS DE ACEPTACIÓN
═══════════════════════════════════════════════
HISTORIA:
Como un [tipo de usuario]
Quiero [acción/meta]
Para que [beneficio/valor]
CRITERIOS DE ACEPTACIÓN:
Happy Path:
- [ ] [Escenario de éxito principal 1]
- [ ] [Escenario de éxito principal 2]
Edge Cases:
- [ ] [Edge case 1]
- [ ] [Edge case 2]
Manejo de Errores:
- [ ] [Escenario de error 1]
- [ ] [Escenario de error 2]
No Funcionales:
- [ ] [Requisito de performance]
- [ ] [Requisito de accesibilidad]
Fuera de Alcance:
- [Explícitamente qué NO está incluido]
- [Para prevenir scope creep]
Ejemplos del Mundo Real
Ejemplo Carrito E-commerce
TAREA: Funcionalidad Agregar al Carrito
CRITERIOS DE ACEPTACIÓN:
Agregando Items:
- [ ] Usuario puede agregar producto al carrito desde página de producto
- [ ] Usuario puede especificar cantidad antes de agregar (1-99)
- [ ] Ícono del carrito muestra conteo actualizado inmediatamente
- [ ] Confirmación "Agregado al carrito" se muestra por 3 segundos
- [ ] Producto con opciones seleccionadas (talla, color) se agrega
Comportamiento del Carrito:
- [ ] Agregar mismo producto aumenta cantidad (no duplica)
- [ ] Carrito persiste entre sesiones (usuarios logueados)
- [ ] Carrito persiste por 30 días (usuarios guest vía cookie)
Edge Cases:
- [ ] Agregar más del inventario disponible muestra mensaje de stock
- [ ] Productos agotados muestran "Notificarme" en lugar de "Agregar"
- [ ] Tamaño máximo del carrito es 50 items únicos
Errores:
- [ ] Error de red muestra "No se pudo agregar. Intente de nuevo."
- [ ] Producto ya no disponible muestra mensaje apropiado
Performance:
- [ ] Agregar al carrito completa en <500ms
- [ ] Carrito se actualiza sin recarga de página
FUERA DE ALCANCE:
- Funcionalidad de wishlist (tarea separada)
- Guest checkout (manejado en tarea de checkout)
Ejemplo Endpoint API
TAREA: Crear Endpoint de Registro de Usuario
CRITERIOS DE ACEPTACIÓN:
Request:
- [ ] POST /api/v1/users/register
- [ ] Acepta body JSON: email, password, name
- [ ] Content-Type: application/json
Validación:
- [ ] Email: formato válido, único en sistema
- [ ] Password: 8+ chars, mayúscula, minúscula, número
- [ ] Nombre: 2-100 caracteres, alfanumérico + espacios
Éxito (201):
- [ ] Retorna user ID, email, nombre
- [ ] NO retorna password
- [ ] Crea usuario en BD con password hasheado
- [ ] Envía email de verificación
- [ ] Loguea evento de registro
Errores:
- [ ] 400: Input inválido (con errores a nivel de campo)
- [ ] 409: Email ya existe
- [ ] 422: Validación falló
- [ ] 429: Rate limited (5 intentos por IP por minuto)
Seguridad:
- [ ] Password nunca se loguea
- [ ] Usa bcrypt con cost factor 12
- [ ] Solo HTTPS
- [ ] CORS configurado para orígenes permitidos
Mejores Prácticas
Para Escribir Criterios
- Ser específico — Números, mensajes exactos, comportamiento preciso
- Ser testeable — Puede verificar pasa/falla objetivamente
- Enfocarse en qué, no cómo — Requisitos, no implementación
- Incluir casos negativos — Qué NO debería pasar
- Definir "terminado" — Sin ambigüedad sobre completar
Refinamiento Colaborativo
PROCESO DE REFINAMIENTO
═══════════════════════
1. BORRADOR: Product owner escribe criterios iniciales
2. REVIEW: Equipo revisa en reunión de refinamiento
3. CLARIFICAR: Desarrolladores hacen preguntas
4. EXPANDIR: Agregar edge cases y escenarios de error
5. CONFIRMAR: QA valida que criterios son testeables
6. FINALIZAR: Todos acuerdan que criterios están completos
PREGUNTAS A HACER:
├── "¿Qué pasa si...?"
├── "¿Hay un máximo/mínimo?"
├── "¿Cómo manejamos errores?"
├── "¿Qué está explícitamente fuera de alcance?"
└── "¿Cómo verificará QA esto?"
Anti-Patrones
ERRORES DE CRITERIOS DE ACEPTACIÓN:
✗ Demasiado vago ("debería funcionar bien")
✗ Demasiado detallado (especificaciones de implementación)
✗ Faltan casos de error
✗ Sin criterios de performance
✗ No revisado por desarrolladores
✗ No revisado por QA
✗ Cambiado a mitad de sprint sin discusión
✗ Sin sección fuera de alcance