Data Quality Tools

Validation and Testing Compared (2026)

Data quality tools check that data is valid, complete, unique and on time, and report or block a load when it's not. Data validation tools run the check as data arrives, data testing tools run it on tables a pipeline has built, and the leading options differ in where they run and how checks are written: dbt tests in the warehouse, Great Expectations in Python, Soda in YAML, Deequ on Spark.

Last updated: Proudly published by: Jeff Wahl10 min read

What are data quality tools?

Data quality tools run checks on data and report the result: is the key unique, is the column populated, is the value in range, did the load arrive on time. Some tools run those checks in your warehouse as SQL. Others run in a Python process or on Spark, or come as a managed service in a cloud platform. Which one fits depends on where your data is when you want to check it, and on who writes the checks.

The same tools answer 3 searches that sound different. Data validation tools check data against a schema or a rule set as it arrives, data testing tools assert facts about tables a pipeline has built, in the way a unit test asserts facts about code, and data quality tools is the umbrella term for both. A check for a unique order_id is a validation when it runs on a landing file and a test when it runs on a finished model, and most tools below will run it in either place.

This guide compares the tools data engineers meet most: dbt tests, Great Expectations, Soda, Deequ and Pandera, plus the checks built into Glue and Snowflake and those in Databricks. It does not rank them. It says what each one does and needs from you, and which situation it suits.

dbt tests, Great Expectations, Soda and Deequ side by side

dbt tests
  • Checks written inYAML and SQL
  • Runs onYour warehouse
  • A check is calledData test
  • Result you getFailing rows
Great Expectations
  • Checks written inPython
  • Runs onSQL and Spark data
  • A check is calledExpectation
  • Result you getResult and Data Docs
Soda
  • Checks written inYAML (SodaCL)
  • Runs onConnected data source
  • A check is calledCheck
  • Result you getPass, fail or error
Deequ
  • Checks written inScala or PyDeequ
  • Runs onApache Spark
  • A check is calledConstraint
  • Result you getMetrics repository

Where in the pipeline a quality check belongs

A pipeline has 3 natural places to look at data after the source. At landing, a validation checks the shape of what arrived: expected columns, types, nulls in required fields. In the warehouse, tests check the model you built: uniqueness, valid relationships, accepted values. At the dashboard end, monitoring checks that the table is fresh and its volume is plausible.

A pipeline of 4 stages, source, landing, warehouse and dashboard, with 3 gates under the stages after the source: validate at landing for schema, types and nulls, test at the warehouse for keys and relationships, monitor at the dashboard for freshness and volumeA pipeline of 4 stages, source, landing, warehouse and dashboard, with 3 gates under the stages after the source: validate at landing for schema, types and nulls, test at the warehouse for keys and relationships, monitor at the dashboard for freshness and volume

An earlier gate protects more of the pipeline, because a bad row caught at landing never reaches the models built on it. A later gate sees more of the truth, because only a built table can show a broken join or a stale refresh. Teams that rely on a single gate usually discover the failures it can't see in production. The depth of the monitoring end is its own subject, covered in the guide to data observability.

Prepare for the interview
01 / Open invite
02min.

Know Data Quality Tools the way the interviewer who asks it knows it.

a Data Quality Tools query, the same shape a screen would give you.
The diff against expected. Where ties broke. What you missed.
sandbox
1source → bronze → silver → gold
2 ingest : CDC + Kafka
3 transform : dbt + Airflow
4 serve : Snowflake
5
Execute your solution0.4s avg.
MicrosoftInterview question
Solve a Data Quality Tools problem

dbt tests: checks that live beside the model

dbt ships 4 generic data tests: unique, not_null, accepted_values and relationships, declared in the YAML next to the model they protect. A singular test is a .sql file whose select returns the failing rows, so any rule you can write as a query becomes a test. dbt test runs them, and with store_failures dbt saves the failing rows to a table so you can look at them instead of rerunning the query.

2 more checks sit in the same project. Source freshness takes warn_after and error_after thresholds and a loaded_at_field, and runs with dbt freshness. Unit tests, available from dbt v1.8, check a model's logic against small hand-written inputs before it is built, which is a different job from checking real data: they run in development and CI, and only SQL models can be unit tested.

The strength of dbt tests is that they cost nothing to add to a project you already run, and they execute in the warehouse next to the data. The limit is the same fact seen from the other side: they check what dbt builds. A raw file that fails before it is loaded, or a Spark job that never touches dbt, needs a check somewhere else. The package dbt-expectations adds more than 60 tests in the style of Great Expectations, written as SQL. The dbt interview questions cover how tests and sources come up in interviews, including severities.

Great Expectations: validation as a Python library

GX Core is a Python library released under the Apache 2.0 license. Its unit is the Expectation, a verifiable assertion about data, and a set of them is an Expectation Suite. The rest of the model says where the data comes from: a Data Source connects to a store, a Data Asset is a table or query result in it, and a Batch Definition tells GX how to slice the asset into the Batch it validates. A Validation Definition ties a Batch Definition to a suite, and a Checkpoint runs several of them and can trigger actions such as an alert, with results written to Data Docs.

That structure is more setup than a YAML file, and it pays off when validation is part of a Python program: a task in an orchestrator that validates a dataframe before writing it, or a check that gates a file drop. Expectations can run against SQL tables and Spark DataFrames, so one vocabulary covers both. The cost is that the checks are code, so whoever reviews them must read Python.

Soda: checks written in YAML

Soda expresses checks in SodaCL, a YAML-based language. A file lists checks per dataset: row_count between 10 and 1000, missing_count(birth_date) = 0, duplicate_count(phone) = 0, freshness (start_date) < 1d, plus schema checks that warn or fail when columns go missing or change type. A scan returns pass or fail per check, with an error when a check can't run, and a check can be set to warn instead of fail.

The current Soda Core v4 is described by its repository as a data quality and data contract verification engine: a contract is a YAML file for one dataset that covers its schema and its data, verified with soda contract verify locally or in a pipeline, and also through Soda Cloud. That shape suits teams where analysts or data owners read and edit the rules, because the file reads like a specification and needs no Python. Check which major version a tutorial uses: v3 and v4 install different packages.

Deequ and Pandera: checks inside Spark and Python jobs

Deequ is an Apache 2.0 library, built on Apache Spark, for defining unit tests for data on large datasets. Its research paper, Automating large-scale data quality verification (Schelter et al., PVLDB 2018), describes computing the metrics for all constraints in few passes over the data. Besides constraints it offers a metrics repository, profiling, anomaly detection over the metrics' history, and constraint suggestion that proposes checks from the data. PyDeequ is its Python interface.

Pandera is an MIT-licensed Python framework that validates dataframes at runtime, for pandas, Polars, Dask, Modin, Ibis and PySpark. A schema is either a DataFrameSchema object or a DataFrameModel class, written like a dataclass, and validation with lazy=True runs every rule before raising so the error report lists all failures, split into schema problems and data problems.

Both live inside the job that handles the data, so the check runs on the same cluster or process, with no second system to schedule. Neither draws a dashboard for you. They fit pipelines written in Spark or Python where the cheapest place to stop bad data is the transform itself.

Data quality checks built into Glue, Snowflake and Databricks

AWS Glue Data Quality is a managed, serverless service built on Deequ. Rules are written in the Data Quality Definition Language (DQDL), it ships more than 25 out-of-the-box rule types, and a data quality score is the percentage of rules that pass. It can recommend rules from your data and detect anomalies with machine learning, and it runs either on tables in the Glue Data Catalog or inside Glue ETL jobs, where it can also identify the failing records.

Snowflake attaches checks to tables with data metric functions (DMFs). A DMF measures one attribute and returns a value, and an expectation pairs it with a pass condition. The feature requires Enterprise Edition, runs on serverless compute billed in credits, and by default evaluates once an hour per table. Its anomaly detection covers volume and freshness.

In Databricks pipelines, an expectation is a constraint on a dataset with 3 failure actions. The default, warn, leaves invalid rows in place and counts them in metrics. Drop removes them before the write, and fail stops the update when a single record violates it. The fail action records no metrics, because the update fails. These checks are the shortest path when the data already lives on one platform, and the least portable: the rules do not move to another warehouse.

The same check, a unique and non-null order_id, in 4 tools

YMLdbt
models:
  - name: orders
    columns:
      - name: order_id
        data_tests:
          - unique
          - not_null

Warn and error thresholds: how many failing rows is too many

A check that must find zero failures is the wrong rule for many columns. Take a orders table of 2,000,000 rows where customer_id is missing on a few guest checkouts. A single test can carry 2 thresholds, warn_if and error_if, each a comparison on the count of failing rows. Set warn_if: ">2,000" (0.1% of the table) and error_if: ">20,000" (1%).

dbt reads error_if first, then warn_if, so 4,300 failing rows is 0.215% of the table: above the warn line of 2,000, below the error line of 20,000, and the test returns "warn". The pipeline continues and the owner is told. The dbt documentation on severity gives the rules. Great Expectations has a similar knob in its mostly argument. Soda and Databricks offer warn levels too.

A threshold needs a baseline, so choose it from what the column looks like on a healthy day rather than from a round number. Pair every not-null or uniqueness check with a row count check as well. A test that asserts no row is bad passes on an empty table, so a load that wrote nothing looks perfect. A check such as Soda's row_count between 10 and 1000 closes that gap.

Which data quality tool fits which situation

Your situationWorth a lookWhy it fits
Every table is built by dbt and the rules are SQLdbt tests and source freshnessThey run in the warehouse with no new system, and the failing rows are one query away.
Data arrives as files or API responses before any modelGreat Expectations, Pandera or SodaA check runs on the batch in a task before the load, so bad data stops at landing.
Analysts or data owners need to read and edit the rulesSoda contracts or dbt YAMLThe rules are declarative files that read like a specification, with no code to review.
Large Spark datasets and checks inside the jobDeequ, PyDeequ or Pandera on PySparkThe check computes its metrics on the same cluster and can keep history for anomaly detection.
All data sits on 1 cloud platform and you want little to runGlue Data Quality, Snowflake DMFs or Databricks expectationsThe service runs the checks and bills them with the platform, in exchange for rules that stay on it.
You must test model logic, not live datadbt unit testsFixed inputs and expected outputs prove the transformation before it touches real rows.

What data quality tools do not catch

Every tool here checks what someone thought to write down. A rule fires on the failure you imagined, and the one you did not imagine passes. Anomaly detection on volume and freshness covers some of that gap by learning a range from history; Deequ and Glue offer it, and so does Snowflake. The wider practice is described in the guide to data observability. The broader discipline of deciding what quality means for a table is in data quality for data engineers.

Checks also need an owner and a place in the run. A failing test nobody reads is a log line. Decide who is told, which failures block the load and which only warn, and where in the DAG the check runs, as part of the pipeline design described in the data pipeline architecture guide. This is also what interviewers probe: how a pipeline detects bad data, and what it does next. Practise those answers with data pipeline interview questions and data pipeline practice problems, and see how the design round asks for them in the system design round.

Data quality tools FAQ

What are data quality tools?+
Data quality tools check that rows are complete and unique and that values are valid and consistent. They also check that loads arrive on time, and they report the failure or block the load when a check fails. They differ in where the check runs (in the warehouse, or outside it in Spark, a Python process or a managed cloud service) and in how the check is written (as SQL or YAML, or as code).
What is the difference between data validation and data testing?+
Validation checks data as it arrives against a schema or a rule set, often before it is stored. Testing asserts facts about tables that a pipeline has already built, such as unique keys and valid relationships. The tools overlap: the same check can run at either point.
Is dbt a data quality tool?+
dbt includes data tests, both generic (unique, not_null, accepted_values, relationships) and singular SQL tests, as well as source freshness checks. Since v1.8 it also has unit tests of model logic. It covers checks that can be written as SQL inside a dbt project, and it doesn't profile data or watch tables it does not build.
Is Great Expectations open source?+
GX Core, the Python library, is released under the Apache 2.0 license. Great Expectations also sells a hosted product, so check which one a tutorial or a job posting means.
Which tool validates data at Spark scale?+
Deequ is a library built on Apache Spark for unit tests for data, with PyDeequ as its Python interface. Great Expectations can also validate Spark DataFrames, and Pandera supports PySpark. AWS Glue Data Quality is a managed service built on Deequ.
Do I need a data quality tool if I already have tests in dbt?+
Not necessarily. If every table you care about is built by dbt and every rule fits in SQL, dbt tests may be enough. A tool outside dbt adds value when data arrives from files or APIs before dbt sees it, when checks must run inside a Python or Spark job, or when you want anomaly detection over history.
Should a failed check stop the pipeline?+
It depends on what the data feeds. A broken primary key in a table that drives billing should stop the load. A small share of nulls in an optional column can warn. Most tools let you set both levels, so a threshold decides which one a failure triggers.
02 / Why practice

The candidate who gets the offer

  1. 01

    Reading a solution is not the same as writing one

    Every engineer who has frozen on a query they had read a dozen times knows the gap. The only preparation that closes it is producing the answer yourself, under time, before the interview does it for you

  2. 02

    76% of hiring managers reject on the coding task, not the resume

    From HackerRank's 2024 Developer Skills Report. Candidates who look strong on paper still fail the live screen if they haven't done timed, executable practice

  3. 03

    System design comes down to the calls you defend out loud

    Ingestion, batch vs streaming, the bronze/silver/gold layers, idempotency, backfill and replay. Sketching the pipeline and naming the failure modes is the signal, not the boxes

Related guides