Unit Testing
Unit testing allows you to validate your SQL modeling logic on small sets of static input data before deploying your models to production. Unlike data tests that verify completed models, unit tests help you catch logical errors during development—bringing the test-driven development approach to data transformations.
Unit testing is available in dbt™ Core v1.8+ and in dbt™ Cloud on the "Latest" release track.
Why Unit Testing Matters
Traditional data tests validate the quality of existing data or the structure of materialized datasets. However, these tests can only be executed after a model has been built. Unit tests serve a different purpose:
Test before building – Validate logic without materializing models
Verify transformations – Ensure your SQL logic handles edge cases correctly
Support test-driven development – Write tests first, then implement the model
Catch errors early – Find bugs before they reach production
Improve code reliability – Maintain confidence during refactoring
When to Use Unit Tests
Unit tests are particularly valuable when your models include:
Complex transformations – Regular expressions, date calculations, window functions
Critical business logic – Calculations that impact important metrics
Known edge cases – Scenarios that have caused issues in the past
Models undergoing refactoring – Changes to existing transformation logic
Frequently used models – Core models that many others depend on
Unit tests complement data tests but serve a different purpose. Data tests verify the quality of your data after models are built, while unit tests validate your transformation logic before deployment.
Unit Test Structure
A unit test in dbt™ consists of:
Mock inputs – Sample data for source tables and referenced models
Model under test – The model whose logic you want to validate
Expected outputs – The exact results you expect after transformation
Example Unit Test
Here's how a unit test is defined in YAML:
Creating Unit Tests
Unit tests are defined in YAML files within your models directory, typically alongside the model they're testing.
Key Components
Test name – Descriptive identifier for the test
Model – The model being tested
Given inputs – Mock data for model dependencies
Expected outputs – The anticipated results
Mock Data Formats
You can provide mock data in several formats:
Dictionary format – Define rows as YAML dictionaries
CSV format – Provide data in CSV format
SQL format – Write SQL queries to generate test data
External fixtures – Reference data from separate files
Running Unit Tests
To run unit tests, use the dbt test command with appropriate selectors:
Unit Testing Special Cases
Incremental Models
When testing incremental models, you can override the is_incremental()
macro to test both full refresh and incremental scenarios:
Ephemeral Models
To test models that depend on ephemeral models, use SQL format for the input:
Limitations & Best Practices
Limitations
Current unit testing in dbt™ has some limitations:
Only supports SQL models (not Python models)
Can only test models in your current project
Doesn't support materialized views
Doesn't support recursive SQL or introspective queries
Requires all table names to be aliased in join logic
Best Practices
Focus on logic, not functions – Test your business logic rather than built-in database functions
Use descriptive test names – Clearly explain what each test is verifying
Test edge cases – Include unusual scenarios your logic needs to handle
Only mock what's needed – Define only the columns relevant to your test
Run in development – Use unit tests during development, not in production
Use in CI/CD – Integrate unit tests into your CI/CD pipeline
Last updated
Was this helpful?