Puedes leer todo sin registrarte. Solo crearemos un perfil anónimo cuando decidas guardar tu progreso.
Lección 2 de 5
Wheels, PyPI y versiones fijadas
Diseña contratos de DataFrame explícitos para que los tests detecten cambios de esquema, nulos, duplicados y semántica, no sólo errores de ejecución.
- Duración
- 17 min aprox.
- Objetivo
- Diseña contratos de DataFrame explícitos para que los tests detecten cambios de esquema, nulos, duplicados y semántica, no sólo errores de ejecución.
- Siguiente paso
- Continuar con la siguiente lección
Ver detalles del módulo
Proyectos Python, dependencias y pruebas
Convierte notebooks en un paquete comprobable con límites claros y entornos reproducibles.
- Diseñar un paquete Python modular
- Gestionar wheels y dependencias
- Probar DataFrames y contratos
02ImplementaciónWheels, PyPI y versiones fijadas
Diseña contratos de DataFrame explícitos para que los tests detecten cambios de esquema, nulos, duplicados y semántica, no sólo errores de ejecución.
+
Wheels, PyPI y versiones fijadas
Diseña contratos de DataFrame explícitos para que los tests detecten cambios de esquema, nulos, duplicados y semántica, no sólo errores de ejecución.
Spark evalúa de forma perezosa, por lo que construir un DataFrame no demuestra que la transformación sea válida. Las pruebas deben materializar un resultado pequeño y comparar esquema, filas y casos borde. Crea fixtures mínimas que incluyan nulos, duplicados, timestamps y valores inválidos; evita copiar datasets productivos con información sensible.
Una transformación testable recibe DataFrames y parámetros ordinarios. Para comparar resultados, ordena por claves deterministas o utiliza utilidades de aserción de DataFrames disponibles en tu stack; nunca dependas del orden natural de particiones. Separa el contrato técnico —tipos y columnas— del contrato de negocio —por ejemplo, un único pedido por ID—.
Modelo mental
Un contrato de DataFrame describe significado además de columnas. Incluye nombres, tipos, nulabilidad, claves, unicidad, rangos, relaciones y reglas temporales; también aclara qué evolución es compatible. Un schema test detecta que amount cambió de decimal a string, pero no que se duplicó cada order_id o se invirtió el signo de devoluciones. Los tests de transformación deben cubrir ejemplos pequeños que representen equivalencias, nulos, duplicados, datos tardíos y límites. Comparar DataFrames exige normalizar orden o usar comparación insensible cuando el orden no forma parte del contrato. El objetivo no es replicar Spark con mocks, sino ejecutar Spark sobre casos precisos y separar lógica de invariantes de calidad de datos productivos.
Especificación de schema, claves, calidad y significado que una transformación promete aceptar y producir para sus consumidores.
Detecta regresiones que compilan y ejecutan correctamente pero alteran significado, unicidad o integridad del producto de datos.Clase de entradas que deberían activar el mismo comportamiento, representada por pocos casos cuidadosamente elegidos en las pruebas.
Aporta cobertura significativa sin enumerar combinaciones infinitas ni depender de enormes copias de producción.Normalización de orden, tipos y representación antes de contrastar dos DataFrames que deben ser semánticamente equivalentes.
Evita fallos por orden distribuido no garantizado y mantiene visibles las diferencias que sí pertenecen al contrato.# tests/test_transforms.py
from orders.transforms import valid_orders
def test_valid_orders_rejects_negative_amounts(spark):
source = spark.createDataFrame(
[(1, 7, "2026-07-20T10:00:00Z", 12.5),
(2, 8, "2026-07-20T11:00:00Z", -4.0)],
"order_id long, customer_id long, ordered_at string, net_amount double",
)
actual = valid_orders(source).orderBy("order_id").collect()
assert [row.order_id for row in actual] == [1]
assert str(actual[0].order_date) == "2026-07-20"El fixture prueba un comportamiento concreto; añade tests separados para nulos, zona horaria y esquema.
Puntos clave
- Materializa acciones pequeñas para ejecutar el plan bajo prueba.
- Compara esquema y contenido con orden determinista.
- Incluye casos borde sintéticos y libres de datos personales.
Evita
- Afirmar sólo que `df.count()` no lanza error sin comprobar valores o esquema.
- Comparar listas no ordenadas y aceptar tests intermitentes por particionado.
Recuerdo activo