Estructura de un caso de prueba completo
Un caso de prueba útil tiene estructura mínima: ID único, Título, Precondición, Pasos numerados, Datos de entrada, Resultado esperado, Resultado actual y Estado. El ID (TC-AUTH-001) permite trazabilidad en bug trackers. El título describe la acción en una línea ("Login exitoso con credenciales válidas"). La precondición lista lo que debe estar listo antes ("Usuario registrado existente").
Los pasos deben ser ejecutables por cualquier QA sin contexto extra. Mal: "Hacer login normal". Bien: "1. Ir a /login. 2. Ingresar email registrado. 3. Ingresar password correcto. 4. Click en botón Iniciar Sesión". Cada paso debería tener resultado esperado verificable, no solo el final.
El resultado esperado debe ser específico y testeable. Mal: "Funciona bien". Bien: "El usuario es redirigido a /dashboard, ve su nombre en el header, y aparece notificación toast de bienvenida". Si no podés verificar el resultado mecánicamente, el caso no sirve para regression testing automatizado.
Tipos de casos: positivos, negativos y edge cases
Para cada feature necesitás tres tipos de casos. Positivos verifican que el happy path funciona: "Login con credenciales correctas funciona". Negativos verifican que los errores se manejan bien: "Login con password incorrecto muestra mensaje claro sin revelar si el email existe". Edge cases exploran límites: "Login con email de 320 caracteres (límite RFC) funciona; 321 caracteres rechaza".
La regla de Boris Beizer: los bugs aparecen en los bordes. Por cada feature, identificá límites: ¿qué pasa con string vacío? ¿con string máximo? ¿con números negativos? ¿con fechas pasadas? ¿con concurrencia? Stripe tiene tests para "tarjeta con CVV de 3 dígitos vs 4 dígitos (Amex)". Esos casos atrapan regresiones que tests felices nunca encuentran.
Una técnica útil: equivalence partitioning. Si tu campo "edad" acepta 0-150, tenés 4 particiones: <0 (inválido), 0-17 (menor), 18-150 (válido), >150 (inválido). Necesitás un caso por partición, no uno por cada número. Eso reduce el set de tests sin perder cobertura. Microsoft y Atlassian usan esta técnica para reducir suites de QA de 10000 a 500 casos manteniendo cobertura.
Errores comunes al escribir casos de prueba
Error #1: casos demasiado abstractos. "TC-001: Probar login" no es caso, es nombre de feature. Cada caso debe testear UN comportamiento específico. Si tu caso tiene "Probar login: válido, inválido, password recovery, 2FA", divididlo en 4 casos. Cada caso es atómico, falla por una sola razón identificable.
Error #2: casos sin datos concretos. "Ingresar password incorrecto" es ambiguo. ¿Qué password? ¿Mismo email correcto? ¿Cuántos intentos? Mejor: "Ingresar email 'test@example.com' (registrado) y password 'wrongpass123' (no es el correcto)". Datos específicos hacen el caso reproducible.
Error #3: resultado esperado vago. "Debería funcionar" no es resultado, es deseo. Mejor: "Status code 200, response body contiene token JWT en field access_token, cookie sessionId seteada con flag HttpOnly". Si tu QA automation no puede assertar esos resultados con código, el caso no es testeable.
Casos de prueba en BDD (Gherkin) y frameworks modernos
El formato Gherkin (Given/When/Then) usado en Cucumber, SpecFlow y Behave reemplaza el formato tabular tradicional con lenguaje natural. "Given user is logged in, When user clicks logout, Then session cookie is cleared and redirected to /login". Es más legible para product managers pero requiere disciplina: cada step debe tener implementación real en código.
Para automatización moderna, frameworks como Playwright y Cypress permiten codificar casos directamente: test('login funciona', async ({ page }) => { await page.goto('/login'); await page.fill('#email', 'test@example.com'); ... }). La ventaja: el caso de prueba ES código ejecutable, no documento separado. La desventaja: requiere dev skills para mantenerlo.
El balance ideal: casos manuales en herramientas como TestRail o Zephyr para QA exploratorio y testing complejo, casos automatizados en Playwright/Cypress para regression de happy paths críticos, y property-based testing con fast-check para edge cases generados aleatoriamente. Stripe, GitHub y Vercel combinan los tres niveles para cobertura completa sin ahogarse en mantenimiento.