El problema
Cuando importás datos de fuentes externas, muchas veces te dicen que cumplen con determinadas características. Que la clave primaria es única. Que ciertos campos nunca vienen nulos. Que los valores posibles de un campo son estos y no otros.
Después te encontrás con sorpresas.
El problema no es que el código de transformación esté mal escrito. El problema es que las suposiciones que hiciste sobre los datos de entrada dejaron de ser ciertas, o nunca lo fueron.
Si no validás esas suposiciones de forma explícita, el error se propaga silenciosamente por todo el pipeline. Y cuando finalmente aparece (en un reporte que no cierra, en un dashboard con números raros), tenés todo un linaje enorme por delante para reconstruir dónde se introdujo el problema.
Tests como contratos con la fuente
Los tests en datos no validan que el código compile o que la query corra. Validan que las suposiciones que estás haciendo sobre los datos sean ciertas.
Cuando testeás que una columna sea única, estás validando un contrato implícito con la fuente. Cuando testeás que un campo no sea nulo, estás verificando que la premisa sobre la que construiste tu transformación sigue siendo válida. Cuando testeás integridad referencial, estás asegurando que las relaciones que asumiste existen realmente.
Estos tests pueden parecer triviales (unique, not_null, accepted_values, relationships), pero la mayor parte de los problemas de calidad en proyectos de ingeniería de datos vienen justamente por este tipo de cosas: claves duplicadas, campos nulos donde no debería haberlos, valores fuera del rango esperado, referencias rotas.
En herramientas como dbt, estos tests se definen de forma declarativa junto con la documentación del modelo. Se ejecutan como parte del pipeline y, cuando fallan, pueden frenar la ejecución o generar alertas según la severidad configurada.
Testear cerca del origen aclara responsabilidades
Si estás trabajando con una tabla de cuentas y asumís que el account_id es único, probablemente después hagas un join por ese campo. Si el account_id viene duplicado y no lo detectaste, vas a romper todos tus números.
El punto es que vos estás suponiendo cosas de la fuente. Y esas suposiciones hay que validarlas, no asumirlas.
Hay otro beneficio importante: cuando testeás cerca del origen, sabés de dónde viene el problema. Si el test falla en la capa de staging sobre datos recién ingestados, el problema viene de la fuente. Si no testeaste ahí y el error aparece tres capas después, no sabés si lo introdujiste vos o si venía de antes. Terminás haciendo trabajo de detective que podrías haberte ahorrado.
Además, si el problema viene de origen, hay mecanismos que se disparan para que alguien se haga cargo. Pero si no está claro dónde se introdujo el error, lo más probable es que el problema quede adosado al área de ingeniería de datos, aunque no corresponda.
Trade-offs y consideraciones
Costo de ejecución
Testear todo en todas partes no tiene sentido. Cada test es una query que se ejecuta contra la base de datos, consume recursos y compite con otras consultas. En entornos cloud, eso también se traduce en costo.
El criterio es testear lo que asumís:
- Si tu transformación depende de que un campo sea único, testeá que sea único.
- Si asumís que ciertos valores están dentro de un rango, validalo.
- Si no estás asumiendo nada sobre un campo, probablemente no necesites testearlo.
Qué hacer cuando falla un test
Frenar el pipeline completo es una decisión drástica. A veces tiene sentido para errores críticos. Otras veces conviene que el pipeline siga, que el error se registre y se notifique, y que alguien lo revise sin bloquear todo el flujo.
Factores para decidir:
- Qué tan crítico es el dato afectado.
- Qué tan maduro está el proceso.
- Qué capacidad tiene el equipo para responder rápido.
Si cada vez que falla algo se frena todo y tardás un día en arreglarlo, el remedio puede ser peor que la enfermedad.
Umbrales vs fallas absolutas
Una práctica útil es manejar umbrales. En lugar de fallar si hay un solo duplicado, podés configurar que falle si el porcentaje de duplicados supera cierto valor.
Pero ojo: si estás procesando incrementalmente y el universo de datos es grande, un umbral sobre toda la tabla puede ocultar que todas las filas nuevas de hoy están mal.
Tests que pierden vigencia
Los tests que definís hoy pueden dejar de tener sentido mañana. Si cambia la lógica de negocio o la naturaleza de la fuente, un test que antes pasaba puede empezar a fallar legítimamente. Eso no significa que haya un error; significa que el test quedó desactualizado.
Hay que monitorearlo y deprecar los tests que ya no aplican, para evitar falsos positivos que nadie mira.
En resumen
Los tests en transformaciones no validan que el código funcione. Validan que las suposiciones que hiciste sobre los datos sigan siendo ciertas.
Testear cerca del origen reduce el costo de detectar problemas y aclara responsabilidades. Testear lo que asumís (unicidad, nulidad, valores válidos, integridad referencial) cubre la mayoría de los problemas reales.
La pregunta no es "¿cuántos tests pongo?". Es "¿qué estoy asumiendo sobre estos datos y cómo me entero si eso deja de ser cierto?".