Lección 5 de 6 · 2 min
Datos de prueba y parametrización
Al terminar sabrás
10 min- Implementar una matriz de casos con parametrize, sin copiar tests
- Generar datos únicos por test con factories para no romper el paralelismo
- Eliminar el flaky con datos deterministas y secretos fuera del código
Construyes: Tu matriz de particiones de teléfono implementada con un solo test parametrizado + factory.
Un test, muchos datos
La matriz de casos de la técnica de particiones (¿recuerdas el curso de QA manual?) se implementa sin copiar tests, con parametrize:
import pytest
CASOS_TELEFONO = [
("+56 9 1234 5678", True, "válido chileno"),
("+56 2 2345 6789", False, "fijo no permitido"),
("12345678", False, "sin código país"),
("", False, "vacío"),
("+56 9 1234 567", False, "un dígito menos (límite)"),
]
@pytest.mark.parametrize("telefono,valido,caso", CASOS_TELEFONO)
def test_validacion_telefono(driver, telefono, valido, caso):
page = BookingPage(driver).open()
page.ingresar_telefono(telefono)
assert page.telefono_es_valido() == valido, f"Falló el caso: {caso}"
Cinco casos, un test, y el reporte muestra cada combinación como resultado independiente — sabes exactamente cuál partición se rompió.
Factories: datos únicos por test
El enemigo del paralelismo son los datos compartidos. Una factory da a cada test datos frescos:
import uuid
def make_cliente(**overrides):
base = {
"nombre": f"Test {uuid.uuid4().hex[:6]}",
"telefono": "+56 9 1234 5678",
"email": f"test-{uuid.uuid4().hex[:6]}@ejemplo.cl",
}
return {**base, **overrides}
def test_reserva(driver):
cliente = make_cliente() # único, no choca con nadie
otro = make_cliente(nombre="Ana") # override explícito cuando importa
La regla: el test declara solo los campos que le importan (los overrides); el resto es ruido válido generado.
Determinismo: la fecha es tu enemiga
# ❌ El test que muere el 31 de diciembre (o en el borde de mes)
fecha = datetime.now() + timedelta(days=1)
# ✅ Congela el tiempo: freezegun
from freezegun import freeze_time
@freeze_time("2026-08-15 10:00:00")
def test_reserva_para_manana(driver):
... # "mañana" es SIEMPRE el 16 de agosto
Math.random, datetime.now(), orden de diccionarios asumido: cada fuente de aleatoriedad en un test es un flaky en incubación.
Secretos fuera del código
# conftest.py — lee de variables de entorno, nunca hardcodees
import os
ADMIN_PASS = os.environ["TEST_ADMIN_PASS"] # explota temprano si falta
Con python-dotenv para local (.env en el .gitignore) y secrets del CI para el pipeline. Una contraseña commiteada en un repo de tests es un incidente de seguridad, no un atajo.
Fija los conceptos con el quiz e implementa tu matriz en el reto.
Compruébalo
0/3Responde sin mirar atrás. Verás la explicación al instante.
1. ¿Qué ventaja da pytest.mark.parametrize sobre copiar el test 5 veces?
2. Un test usa datetime.now() + timedelta(days=1). ¿Cuál es el riesgo?
3. ¿Dónde deben vivir las contraseñas de prueba?
Reto: matriz completa parametrizada
Toma tu matriz de particiones del formulario de reservas (curso QA manual, lección 3) e impleméntala completa con un solo test parametrizado + factory.
Compara: ¿cuántas líneas tendrías con copy-paste?