Skip to content
Home
Data Quality Testing: Ensuring Reliable Data Pipelines

Data Quality Testing: Ensuring Reliable Data Pipelines

Data Engineering Data Engineering 8 min read 1624 words Beginner ExcellentWiki Editorial Team

Data quality is the biggest hidden cost in data engineering. Gartner estimates that poor data quality costs organizations an average of $12.9 million annually. Bad data leads to broken dashboards, incorrect business decisions, and lost trust in analytics. A systematic approach to data quality — encompassing validation, monitoring, testing, and governance — is essential for any organization that depends on data-driven decision-making. The book Fundamentals of Data Engineering by Joe Reis and Matt Housley emphasizes that data quality is not a one-time project but an ongoing practice embedded into every stage of the data lifecycle.

Dimensions of Data Quality

Data quality is multi-dimensional. Each dimension captures a different aspect of data reliability and requires distinct validation approaches:

DimensionDefinitionExample
AccuracyData reflects real-world entities correctlyCustomer email matches known contact information
CompletenessNo missing required valuesAll orders have a valid customer_id
ConsistencySame values across systemsCurrency format matches between source and warehouse
TimelinessData is current and available when neededSales data reflects today’s transactions
UniquenessNo unwanted duplicate recordsEach order_id appears exactly once
ValidityData conforms to defined schemas and rulesAge is an integer, not a text string

A comprehensive data quality program monitors all six dimensions. Neglecting any one leads to data issues that compound over time. For example, a pipeline that validates uniqueness and completeness but ignores freshness might catch duplication but miss the fact that no new data has arrived for three days.

Validation at Ingestion

The first line of defense is validating data as it enters the pipeline. Schema validation ensures that incoming data matches the expected structure, types, and constraints before it enters the main processing flow. Tools like Great Expectations, Pydantic, and JSON Schema provide declarative validation that can be applied at the ingestion layer.

from pydantic import BaseModel, Field

class Order(BaseModel):
    order_id: int = Field(gt=0)
    customer_id: int = Field(gt=0)
    amount: float = Field(gt=0)
    currency: str = Field(pattern=r'^[A-Z]{3}$')
    created_at: datetime

def validate_order(raw: dict) -> Order:
    try:
        return Order(**raw)
    except ValidationError as e:
        send_to_dead_letter_queue(raw, e)
        raise

Common validation rules include NOT NULL constraints for required fields, type checks for data type correctness, range checks for values within expected bounds, format checks for email addresses and phone numbers using regex patterns, and referential integrity checks against dimension tables. Records that fail validation should be routed to a dead letter queue for investigation rather than silently dropped, ensuring data quality issues are visible and actionable.

Data Contracts

A data contract is a formal, versioned agreement between data producers and consumers. It specifies the schema, semantics, SLAs, and ownership of a dataset. Data contracts prevent breaking changes from propagating downstream without notification, similar to how API contracts govern microservice communication.

dataset: orders
version: 1.2
schema:
  fields:
    - name: order_id
      type: integer
      required: true
      constraints: [unique]
    - name: amount
      type: float
      required: true
      constraints: [min: 0, max: 1000000]
slas:
  freshness: 1h
  completeness: 0.99
owners:
  - team: payments
    contact: payments-team@company.com

Adopting data contracts requires a cultural shift: producers must notify consumers before changing schemas, and consumers must agree to reasonable constraints. Tools like Apache Avro’s schema registry with compatibility checks, Great Expectations with cross-team expectations, and dbt’s built-in contract feature (introduced in dbt v1.5) provide technical enforcement mechanisms for data contracts.

Anomaly Detection

Statistical Methods

Automated anomaly detection monitors for unexpected changes in data patterns, catching issues that rule-based validation might miss. Common statistical methods include Z-score analysis for normally distributed metrics and interquartile range (IQR) analysis for non-normal distributions.

def detect_anomalies(df, column, method='zscore', threshold=3):
    if method == 'zscore':
        zscores = (df[column] - df[column].mean()) / df[column].std()
        return df[abs(zscores) > threshold]
    elif method == 'iqr':
        Q1 = df[column].quantile(0.25)
        Q3 = df[column].quantile(0.75)
        IQR = Q3 - Q1
        return df[(df[column] < Q1 - 1.5*IQR) | (df[column] > Q3 + 1.5*IQR)]

Key Metrics to Monitor

Track these metrics over time and alert on significant deviations that could indicate upstream issues:

  • Row count: A sudden drop may indicate a pipeline failure, source system outage, or connectivity issue
  • Null rate: A sudden increase often means a source schema change or application bug introduced nullable columns
  • Distinct values: Unexpected new values or missing expected values can signal bad data entering the system
  • Distribution shifts: Changes in value ranges or statistical distributions point to upstream logic changes
  • Freshness: The time since the last data arrival — staleness indicates pipeline delays or failures

Alerting Tiers

SeverityResponseExamples
WarningEmail notification, Slack messageMinor null rate increase, slight throughput slowdown
CriticalOn-call page, PagerDuty alertPipeline halted, zero rows loaded, severe data corruption
Auto-fixAutomated retry, failoverTransient API failure, connection timeout, throttling

Testing Data Pipelines

Testing data pipelines is more complex than testing application code because data changes over time and edge cases may not appear in test datasets. A comprehensive testing strategy includes multiple levels of validation.

Unit Tests

Test individual transformation functions in isolation with known inputs and expected outputs. Unit tests validate business logic and catch regressions early in the development cycle:

def test_clean_email():
    assert clean_email("  USER@Example.COM  ") == "user@example.com"
    assert clean_email(None) is None

Integration Tests

Test end-to-end pipeline behavior with a small, representative dataset. Integration tests catch issues that unit tests miss, such as incompatible type handling between systems, network connectivity problems, and unexpected data formats:

def test_etl_pipeline():
    test_input = [{"id": 1, "name": "Alice"}]
    expected = [{"id": 1, "name": "ALICE", "name_length": 5}]
    result = run_pipeline(test_input)
    assert result == expected

Data Diff Tests

Compare production datasets to test or staging datasets to detect unexpected changes. These tests are particularly valuable after schema changes or pipeline refactoring to verify that results are consistent:

SELECT * FROM prod.orders
EXCEPT
SELECT * FROM test.orders

Freshness Tests

Verify that data arrives on schedule and within expected time windows. Freshness tests are the most common data quality check in production because they detect silent pipeline failures:

SELECT CASE
    WHEN MAX(created_at) >= NOW() - INTERVAL '1 hour'
    THEN 'PASS'
    ELSE 'FAIL'
END AS freshness_check
FROM orders;

Production Data Quality Tools

ToolTypeKey Features
dbt testsBuilt-innot_null, unique, accepted_values, relationships, custom SQL tests, dbt build integration
Great ExpectationsStandaloneDeclarative expectations, automated data profiling, data docs generation, cross-database
Soda CoreOpen sourceYAML-based checks, CLI and Python library, cross-database support, automated monitoring
DeequSpark-basedMetrics computation, constraint verification, data profiling on Spark DataFrames
Monte CarloManagedEnd-to-end observability, lineage-based monitoring, automated anomaly detection

Common Failure Modes

Failure ModePrevention Strategy
Silent nullsNOT NULL constraints on critical columns with automated alerting
Duplicate recordsUpsert logic with unique key enforcement and deduplication checks
Late-arriving dataWatermark management with freshness thresholds and escalation policies
Schema driftSchema registry with backward-compatibility checks and automatic alerting
Pipeline silenceFreshness alerts with escalation policies - if data stops flowing, notify immediately
Off-by-one datesAutomated date boundary tests comparing date ranges across sources and targets

The Data Quality Mindset

Effective data quality is a practice, not a tool purchase. It requires embedding quality checks into every pipeline stage, documenting assumptions about data, and treating data pipelines with the same rigor as production software. When a quality issue is discovered, fix it upstream at the source rather than patching symptoms downstream — this prevents the same issue from affecting other consumers.

Automated data quality monitoring provides early warning of problems, reducing the time between data degradation and detection from days to minutes. Organizations with mature data quality practices detect issues within minutes rather than days, preventing bad data from reaching dashboards, reports, and ML models. The Data Quality: Concepts, Methodologies and Techniques book by Carlo Batini and Monica Scannapieco provides a comprehensive framework for building data quality programs that scale with organizational growth.

Frequently Asked Questions

How many data quality tests are enough? Focus on critical paths first. Test every column that appears in executive dashboards or feeds ML models. As a rule of thumb, start with uniqueness and NOT NULL tests on primary keys, accepted values on categorical columns, and range checks on numeric fields. Add tests incrementally as you discover new failure modes. A mature data quality program typically includes tests for 20-40% of columns, prioritizing those with business impact.

What is the difference between data quality monitoring and data observability? Data quality monitoring checks specific, predefined rules — is this column null-free, are these values within accepted ranges. Data observability provides a broader view of data health including freshness, volume trends, value distributions, schema changes, and lineage — detecting issues you did not think to test for explicitly. Observability tools use machine learning to establish baselines and surface anomalies without manual rule configuration.

Should I block pipelines on data quality failures? For critical systems — financial reporting, regulatory data, production ML models — yes, block the pipeline to prevent bad data from reaching consumers. For exploratory data or non-critical dashboards, route bad data to a quarantine area and alert the team rather than blocking the entire pipeline. This balances data quality with data availability, recognizing that zero bad data is rarely achievable without sacrificing timeliness.

How do I handle schema changes from source systems? Implement a schema registry that enforces compatibility checks. Producers register schema changes before deploying, and the registry validates whether the change is backward-compatible using configurable compatibility modes. Incompatible changes require consumer review and approval before deployment. This process prevents surprise schema changes from breaking downstream pipelines.

Can data quality be fully automated? Rules-based checks for known patterns can be fully automated, but defining what “good” data looks like requires human domain knowledge for each dataset. The most effective approach combines automated monitoring for known patterns and statistical anomalies with manual investigation of novel issues. ML-based observability tools can detect anomalies without explicit rules, but they still require human judgment to diagnose root causes and determine appropriate responses.

Analytical SQL GuideData Orchestration GuideStreaming Data Guide

Section: Data Engineering 1624 words 8 min read Beginner 756 articles in section Report inaccuracy Back to top