Direct answer
Promoting an ETL change from development to production should pass through unit tests of the transformation logic, integration tests against a realistic (if smaller) dataset, and a data-regression check comparing the new pipeline's output against a known-good baseline, with automatic promotion allowed only when all of those pass cleanly and a human sign-off required whenever the regression check flags a meaningful, unexplained difference.
Structured elaboration
- Unit tests: verify individual transformation functions in isolation (a specific aggregation, a specific join, a specific cleaning rule) against small, hand-crafted inputs with known expected outputs.
- Integration tests: run the full pipeline (or a meaningful slice of it) against a realistic sample dataset, verifying the stages wire together correctly and produce sane output end to end, not just that each function works alone.
- Data-regression tests: run the new pipeline version against the same input the current production pipeline processed, and diff the output against production's actual historical output (or a maintained golden baseline); this catches unintended behavior changes that unit and integration tests, written before the change, wouldn't necessarily anticipate.
- Statistical checks: beyond exact-match diffing, checks like row-count deltas, null-rate changes, and distributional shifts in key columns catch subtler regressions (a join that silently drops rows, a transformation that shifts a distribution) that an exact-diff comparison might not clearly flag if some day-to-day variation is expected.
- Sampling strategy: for large datasets, running a full-scale regression comparison on every change may be too slow or expensive; a representative sample (stratified to include known edge cases, not just random rows) keeps the check fast while still catching most classes of regression.
- Promotion criteria: automatic promotion when the regression check shows no meaningful diff (within an agreed tolerance) and all other checks pass; manual sign-off required when the regression check flags a difference, since only a human can currently judge whether a flagged difference is an intended behavior change or a genuine bug.
Worked example
A change to a customer-lifetime-value calculation pipeline passes unit tests of the updated aggregation logic and an integration test against a sampled dataset. The data-regression check runs the new pipeline against last week's real input and diffs the output against what production actually produced for the same input: 99.7% of rows match exactly, with the 0.3% difference traced to an intentional rounding-behavior fix the change was meant to make. Because the diff was both small and explainable, it was flagged for a quick human review (confirming the difference matched the intended fix) rather than blocking promotion outright, and passed with sign-off.
Trade-offs & pitfalls
The biggest risk is treating "all tests passed" as sufficient without a data-regression comparison against real historical output, since ETL bugs frequently show up as subtle behavior changes (a join cardinality shift, a rounding difference) that unit and integration tests written before the bug existed have no way to anticipate; the regression check against real prior output is what actually catches "this pipeline now behaves differently," not just "this pipeline behaves as its own tests expect."