A dbt test is a declarative data quality assertion, written in SQL or defined in YAML configuration, that validates assumptions about tables and models within a dbt project. It is a core component of the data build tool framework, enabling test-driven data development. Tests are executed via the dbt test command and check for conditions like column uniqueness, non-null values, referential integrity between models, and adherence to custom business logic. Results are logged, providing a clear audit trail of data health.
Glossary
dbt Test

What is a dbt Test?
A dbt test is a declarative data quality check, defined within the dbt (data build tool) framework, that validates assumptions about the structure and content of data in tables and models.
Tests are categorized as generic (pre-built for common constraints like unique and not_null) or singular (custom SQL assertions). They are defined in .yml files alongside model definitions, promoting data quality as code. When integrated into a CI/CD pipeline, failing tests can act as pipeline-gated checks, preventing flawed data from propagating. This embeds validation directly into the transformation layer, shifting quality left and making data reliability a shared, automated engineering responsibility.
Core Characteristics of dbt Tests
dbt tests are declarative data quality checks defined as code within the dbt framework. They validate assumptions about data in tables and models, such as uniqueness and referential integrity, and are executed as part of the data build process.
Declarative & Configuration-Driven
dbt tests are defined declaratively using YAML configuration files or simple SQL SELECT statements. Instead of writing procedural code to check data, you specify what condition the data must satisfy (e.g., not_null, unique). The dbt test execution engine interprets this configuration and runs the appropriate validation query. This approach separates the test logic from the execution engine, making tests portable, easy to version control, and less error-prone than custom scripting.
- Example: A YAML block defining a
not_nulltest on auser_idcolumn. - Key Benefit: Enforces data quality as code, allowing tests to be reviewed, shared, and automated alongside transformation logic.
Built-in Generic & Custom Singular Tests
dbt provides two primary test types. Generic tests (like unique, not_null, accepted_values, relationships) are reusable validations applied to columns via YAML configuration. Singular tests are one-off, custom SQL queries that return failing rows; they are ideal for validating complex business logic that generic tests cannot cover.
- Generic Test Example:
relationshipstest ensures referential integrity between aorders.customer_idcolumn and acustomers.idcolumn. - Singular Test Example: A SQL file that checks if a derived
profit_margincolumn is always below 100%. - Separation of Concerns: This duality allows teams to standardize common checks while retaining flexibility for domain-specific validation.
Integrated into the dbt DAG
Tests are nodes within dbt's Directed Acyclic Graph (DAG) of data transformations. When you run dbt test, the framework understands the dependencies between your models and tests, ensuring tests run on the correct, materialized data. Tests can be executed on specific models, directories, or tags, providing granular control.
- Pipeline-Gated Execution: Tests can be configured to run immediately after a model is built, acting as a quality gate that fails the pipeline if data assumptions are violated, preventing bad data from propagating downstream.
- Dependency-Aware: The test for a
stagingmodel will run before the test for a downstreammartmodel that depends on it, ensuring validation occurs in the correct order.
SQL-Based & Warehouse-Native
All dbt tests are compiled into standard SQL SELECT statements that are executed directly in your data warehouse (e.g., Snowflake, BigQuery, Redshift). The test "passes" if the query returns zero rows; any returned rows are considered failures. This warehouse-native approach leverages the power and scalability of modern cloud platforms.
- Performance: Testing happens where the data lives, eliminating costly data movement.
- Transparency: The generated SQL is inspectable, making it easy to debug why a test failed by examining the failing rows.
- Consistency: Uses the same connection and compute credentials as your dbt models, ensuring a unified environment.
Results as Data & Operational Integration
dbt writes test results to a table in your warehouse (typically dbt_test__audit), turning validation outcomes into queryable data. This enables building custom dashboards, tracking test failure rates over time, and setting up alerts. The results structure includes the test name, status, execution time, and the specific failing rows.
- Observability: Facilitates integration with broader data observability platforms by exposing test results via a clean data interface.
- Historical Analysis: Teams can analyze trends, such as which models or tests fail most frequently, to prioritize data quality investments.
- Alerting: Can be integrated with tools like Slack or PagerDuty by querying the results table after a run.
Complement to Broader Data Quality Frameworks
While dbt tests are excellent for validating the output of transformations defined within dbt, they are often part of a larger data quality posture. They typically serve as unit and integration tests for the dbt-managed layer of the data stack.
- Scope: Best for testing business logic and structural integrity after transformation. They are less suited for monitoring data drift in source systems or validating raw, untransformed data at ingestion.
- Synergy: Often used alongside specialized tools like Great Expectations or Soda Core for profiling, monitoring, and testing non-dbt pipelines or raw data sources. dbt tests act as the quality gate for the "trusted" data layer.
How dbt Tests Work: Mechanism and Execution
A dbt test is a declarative data quality check, defined in SQL or YAML, that validates assumptions about tables and models within the dbt (data build tool) framework.
A dbt test is executed as a SQL query that returns failing rows. The core mechanism is declarative: you define the expected condition (e.g., unique, not_null, relationships), and dbt's test execution engine compiles it into a SELECT statement that identifies violations. For a uniqueness test, this query selects duplicate values; for a referential integrity test, it finds orphaned foreign keys. Tests run within your data warehouse, leveraging its compute, and results are logged for review.
Execution is managed via the dbt test command, which runs tests based on selection criteria (e.g., on a specific model). Tests can be configured as pipeline-gated checks that fail the run or as warnings. Results are aggregated into a summary, showing pass/fail status and the failing rows. This integrates with data observability platforms by exposing results, enabling continuous testing and monitoring of data quality gates within the broader data reliability engineering practice.
dbt Test vs. Other Data Testing Approaches
A comparison of dbt Test's declarative, SQL-centric testing model against other common frameworks and methodologies for automated data quality validation.
| Feature / Characteristic | dbt Test | Programmatic Assertions (e.g., Python) | External Data Quality Platforms (e.g., Great Expectations, Soda) |
|---|---|---|---|
Primary Paradigm | Declarative (YAML/SQL) | Imperative (Code) | Declarative (Configuration/Code) |
Tightness of Integration with Transformation Logic | |||
Native Execution within Data Pipeline | Varies (API-based) | ||
Test Definition Location | Alongside models in project | Separate scripts or pipeline code | External configuration files or UI |
Primary Test Author | Analytics/Data Engineer | Data/Software Engineer | Data Engineer, Data Steward |
Test Orchestration & Scheduling | Via dbt Cloud/dbt Core | Custom (Airflow, Prefect, etc.) | Native scheduler or external orchestrator |
Built-in Test Types | Generic (unique, not_null, etc.) & Singular (custom SQL) | Fully custom | Extensive library (freshness, distribution, regex, etc.) |
Result Storage & History | Within run artifacts (logs, JSON); requires external tool for history | Custom implementation required | Native centralized database & UI |
Alerting & Incident Management | Basic (run failures); requires integration | Fully custom implementation | Native integrations (Slack, PagerDuty, etc.) |
Data Profiling & Discovery | Limited (via | None (must be built) | Core feature |
Data Lineage Integration | Native (tests are nodes in dbt DAG) | None | Varies (often separate from transformation lineage) |
Learning Curve for Basic Use | Low | High | Medium |
Cost for Core Functionality | Open-source (dbt Core) | Open-source (custom code) | Freemium or commercial license |
Ideal Use Case | Testing transformations within a dbt project | Low-level validation in custom Python pipelines | Organization-wide quality monitoring across heterogeneous sources |
Common dbt Test Examples and Use Cases
dbt tests are declarative SQL or YAML statements that validate data integrity and business logic. This section details the most common test types and their practical applications in data pipelines.
Built-in Generic Tests
dbt provides four core, pre-built tests that validate fundamental data properties without custom SQL. These are the most commonly used tests for basic data hygiene.
unique: Ensures all values in a specified column (or combination of columns) are distinct. Essential for primary keys.not_null: Verifies that a column contains noNULLvalues, enforcing completeness for critical fields.accepted_values: Confirms that all data in a column matches a predefined list of allowed values (e.g.,status IN ('active', 'inactive', 'pending')).relationships(Referential Integrity): Validates that every value in a child column exists in a parent column, enforcing foreign key constraints.
Example YAML definition:
yamlmodels: - name: orders columns: - name: order_id tests: - unique - not_null - name: customer_id tests: - relationships: to: ref('customers') field: customer_id
Custom Singular Tests
Singular tests are bespoke SQL queries where a result set indicates a test failure. They are used for complex, one-off validation logic that generic tests cannot cover.
- Structure: A
.sqlfile in thetests/directory containing aSELECTstatement. Any rows returned by the query are interpreted as failing records. - Use Cases:
- Validating multi-column business logic (e.g.,
discount_amount <= order_total). - Checking for orphaned records across multiple tables.
- Enforcing sophisticated date logic (e.g.,
ship_date >= order_date). - Identifying statistical outliers beyond simple thresholds.
- Validating multi-column business logic (e.g.,
Example (tests/ship_date_after_order_date.sql):
sqlSELECT order_id, order_date, ship_date FROM {{ ref('orders') }} WHERE ship_date < order_date -- If this returns rows, the test fails.
Custom Generic Tests
Custom generic tests are parameterized SQL macros that can be reused across multiple columns or models, promoting consistency and reducing code duplication.
- Structure: Defined as a Jinja macro in a
.sqlfile within themacros/directory. They accept arguments likecolumn_nameandmodel. - Use Cases:
- Financial Data: Ensuring debits and credits sum to zero for a ledger.
- ID Format Validation: Checking that a column matches a specific regex pattern (e.g., UUID, email).
- Freshness Thresholds: Testing if a timestamp column is within an acceptable range of the current time.
- Percentage Bounds: Verifying a column's value is between 0 and 100.
Example macro (macros/test_value_between.sql):
sql{% test value_between(model, column_name, min_value, max_value) %} SELECT * FROM {{ model }} WHERE {{ column_name }} < {{ min_value }} OR {{ column_name }} > {{ max_value }} {% endtest %}
Usage in YAML:
yamlcolumns: - name: satisfaction_score tests: - value_between: min_value: 0 max_value: 10
Schema & Data Type Tests
These tests validate the structure and formatting of data, ensuring it aligns with expected contracts and downstream consumption needs.
- Schema Tests: While not a native dbt test type, schema validation is achieved via
dbt buildordbt runcoupled with tests. The compilation and execution of models inherently validates SQL syntax and references. Formal schema contracts are often enforced via pipeline-gated tests on column existence and data type. - Data Type Validation: Implemented using custom generic tests or singular tests.
- Checking that a numeric column contains only integers.
- Ensuring a
VARCHARcolumn does not exceed a defined maximum length. - Verifying a
DATEcolumn has no invalid or out-of-range dates.
- Integration with Data Contracts: These tests operationalize the guarantees of a data contract, acting as the enforceable validation layer for schema stability and type safety.
Business Logic & Integrity Tests
This category encompasses the most valuable tests, which encode critical domain knowledge and ensure data accurately reflects real-world rules.
- Aggregate Logic: Testing that summed totals in summary tables match granular transaction tables.
- Derived Column Accuracy: Validating that a calculated column (e.g.,
revenue = quantity * unit_price) is computed correctly. - Hierarchical Integrity: Ensuring roll-up relationships are maintained (e.g., all city-level records map to a valid country).
- Uniqueness Across Sources: Confirming there is no overlap or duplication of key identifiers when data is merged from multiple systems.
- Temporal Consistency: Checking that slowly changing dimensions (SCD) are applied correctly and history is preserved.
These tests move beyond basic hygiene to protect the business correctness of data products. They are often the most complex to write but provide the highest return on investment by preventing costly decision-making errors.
Test Execution & Orchestration
Understanding how and when tests run is crucial for integrating them into a Continuous Testing paradigm.
- Command-Line Execution:
dbt test: Runs all tests on all models in the project.dbt test --select test_type:singular: Runs only singular tests.dbt test --select model_name+: Runs tests for a specific model and all its downstream dependencies.
- Pipeline Integration:
- As a Quality Gate: Tests are executed after
dbt runin a CI/CD pipeline. A single test failure can be configured to fail the entire job, blocking the promotion of bad data. - In Production: A subset of non-destructive smoke tests or canary tests can be run on production data to monitor health.
- As a Quality Gate: Tests are executed after
- Test Severity: Tests can be configured as
ERROR(fails the run) orWARN(logs a warning but allows the run to proceed). - Result Handling: Results are logged to the command line and stored in the data warehouse, enabling aggregation in dashboards for test coverage and trend analysis.
Frequently Asked Questions
A dbt test is a declarative data quality check, defined in SQL or YAML within the dbt (data build tool) framework, that validates assumptions about data in tables and models. This FAQ addresses common questions about its implementation, mechanics, and role in automated data testing.
A dbt test is a declarative data quality assertion, defined as SQL or YAML configuration within the dbt framework, that validates assumptions about data in tables and models. It works by executing a SQL query that returns failing rows; an empty result set indicates a pass, while any returned rows indicate a failure. Tests are defined in a schema.yml file or as generic test files and are executed via the dbt test command, which compiles the test logic, runs it against the target data warehouse, and reports results. Core mechanics include:
- Declarative Syntax: Tests specify what condition the data must satisfy (e.g.,
unique,not_null) rather than how to check it. - Query-Based Validation: Each test is transpiled into a
SELECTstatement that identifies violating records. - Integrated Execution: Tests run within the same environment and connection as dbt models, ensuring consistent context.
- Result Aggregation: Outcomes are summarized in the CLI and can be logged to a
run_results.jsonfile for integration with data observability platforms.
Enabling Efficiency, Speed & Accuracy
Intelligent Analysis, Decision & Execution
We build AI systems for teams that need search across company data, workflow automation across tools, or AI features inside products and internal software.
Talk to Us
Search across company data
Give teams answers from docs, tickets, runbooks, and product data with sources and permissions.
Useful when people spend too long searching or get different answers from different systems.

Automate internal workflows
Use AI to route work, draft outputs, trigger actions, and keep approvals and logs in place.
Useful when repetitive work moves across multiple tools and teams.

Add AI to products and internal tools
Build assistants, guided actions, or decision support into the software your team or customers already use.
Useful when AI needs to be part of the product, not a separate tool.
Related Terms
dbt tests are a core component of a broader ecosystem of automated data quality practices. These related concepts define the frameworks, methodologies, and complementary tools used to build reliable, test-driven data pipelines.
Data Quality Rule
A declarative or programmatic statement that defines a condition data must satisfy to be considered valid. While a dbt test is a specific implementation within the dbt framework, a data quality rule is the abstract concept it enforces.
- Examples: A column must be non-null, values must fall within a specified range, a foreign key must reference an existing primary key.
- Implementation: Can be codified in SQL, YAML (like dbt), Python (e.g., Great Expectations), or other configuration formats.
- Purpose: Provides the machine-readable specification for what "good data" means for a given asset.
Assertion (Data)
A programmatic check within a data pipeline that actively verifies a specific condition about the data and raises an error or warning if the condition is false. A dbt test is a type of data assertion.
- Key Mechanism: Executes a query; if it returns any rows (representing violations), the assertion fails.
- Runtime Context: Can be run as a pipeline-gated check (blocking) or as a monitoring alert (non-blocking).
- Contrast with Rule: An assertion is the execution of a rule. The rule defines the condition; the assertion tests it.
Declarative Testing (Data)
An approach to data quality where tests are specified as configuration stating what the data condition should be, rather than how to check it programmatically. dbt tests are a prime example of declarative testing.
- Syntax: Uses YAML or SQL-based DSLs (Domain-Specific Languages) to define constraints (e.g.,
not_null,unique). - Advantage: Separates the test definition from the execution engine, making tests more portable, readable, and maintainable.
- Framework Examples: dbt, Soda Core, and the expectation suites in Great Expectations all employ declarative paradigms.
Test-Driven Development (Data)
A software development methodology applied to data engineering where data quality tests are written before the data pipeline code is built. dbt tests are a foundational tool for implementing this practice.
- Workflow: 1. Define expected output schema and quality rules (as dbt tests). 2. Write the SQL transformation model. 3. Run tests to validate the model meets specifications.
- Benefit: Ensures the pipeline is built to satisfy explicit quality requirements from the start, reducing defects and clarifying intent.
- Outcome: Produces a documented, verifiable data asset with built-in quality guarantees.
Pipeline-Gated Test
A data quality test whose failure prevents a data pipeline from proceeding to the next stage. When a dbt test is configured to run as part of a model's materialization and set to fail fast, it acts as a pipeline gate.
- Function: Serves as a quality gate to block bad data from propagating downstream to consumers and dependent models.
- Placement: Typically executed immediately after a model is built or loaded, before any downstream processes begin.
- Contrast: Differs from monitoring tests run in production, which alert on issues but do not halt pipeline execution.

About the author
Prasad Kumkar
CEO & MD, Inference Systems
Prasad Kumkar is the CEO & MD of Inference Systems and writes about AI systems architecture, LLM infrastructure, model serving, evaluation, and production deployment. Over 5+ years, he has worked across computer vision models, L5 autonomous vehicle systems, and LLM research, with a focus on taking complex AI ideas into real-world engineering systems.
His work and writing cover AI systems, large language models, AI agents, multimodal systems, autonomous systems, inference optimization, RAG, evaluation, and production AI engineering.
Partnered with leading AI, data, and software stack.
How We Work
Custom AI workflows for your Business
One-fit-all AI don't work for modern businesses. At Inferensys, we aim to understand your business & custom requirements; which we use to define most efficient agentic workflows, the data, and the tools for your business.
01
Review the use case
We understand the task, the users, and where AI can actually help.
Read more02
Pick the right approach
We define what needs search, automation, or product integration.
Read more03
Build the first useful version
We implement the part that proves the value first.
Read more04
Improve from there
We add the checks and visibility needed to keep it useful.
Read moreThe first call is a practical review of your use case and the right next step.
Talk to Us