ServicesAboutNotesContact Get in touch →
EN FR
Note

dbt Unit Test CLI Commands

How to run, filter, debug, and exclude dbt unit tests from the command line — including output interpretation and production exclusion patterns.

Planted
dbttesting

dbt provides fine-grained control over which unit tests run and when. The key mechanism is the test_type:unit selector, which separates unit tests from data tests in all CLI commands. This separation is fundamental to how unit tests fit into your workflow — they run in different contexts (CI vs. production) and serve different purposes (logic verification vs. data health).

Running Unit Tests

Terminal window
# Run all unit tests
dbt test --select test_type:unit
# Run all data tests (generic + singular)
dbt test --select test_type:data
# Run all tests (unit + data)
dbt test

The test_type:unit and test_type:data selectors are the primary way to separate the two categories. In your daily workflow, you’ll typically run unit tests during development (to verify your logic changes) and data tests after building models (to verify data health).

Filtering Unit Tests

dbt’s selector syntax works the same way for unit tests as it does for everything else:

Terminal window
# Run unit tests for a specific model
dbt test --select mrt__core__customers,test_type:unit
# Run unit tests with a specific tag
dbt test --select tag:critical,test_type:unit
# Run a specific unit test by name
dbt test --select test_mrt_core_customers_email_validation

The comma acts as an intersection — mrt__core__customers,test_type:unit means “tests that are both associated with mrt__core__customers AND are unit tests.” Without the test_type:unit qualifier, you’d also get the model’s generic data tests.

Running a test by name doesn’t need the test_type qualifier since the name is already unique.

Tag-based filtering is particularly useful during development. If you’ve tagged your tests by domain (finance, marketing, core), you can run just the tests relevant to your current work:

Terminal window
# Only run finance-related unit tests
dbt test --select tag:finance,test_type:unit

Building and Testing Together

The dbt build command runs models and tests in DAG order. By default, it includes both unit tests and data tests:

Terminal window
# Build models and run all tests (unit + data)
dbt build
# Build but exclude unit tests
dbt build --exclude-resource-type unit_test

The --exclude-resource-type flag (dbt 1.9+) is the clean way to skip unit tests during production builds. You can also set this as an environment variable for production environments:

Terminal window
export DBT_EXCLUDE_RESOURCE_TYPES=unit_test
dbt build

This is important because unit tests use mocked data and add no value in production. They belong in CI and local development only. Running them in production wastes compute and can cause confusion when mocked-data tests interact with real warehouse state.

Interpreting Output

A passing test is straightforward:

PASS test_mrt_core_customers_email_validation

A failing test shows a diff between expected and actual output:

FAIL test_mrt_core_customers_email_validation
Got:
customer_id | is_valid_email
1 | false
Expected:
customer_id | is_valid_email
1 | true

The diff format makes it immediately clear what went wrong. In this case, the model returned false for is_valid_email when the test expected true. Either the model logic has a bug, or the test expectation is wrong.

For more complex failures — especially when the issue is in the generated SQL rather than the logic — add --debug:

Terminal window
dbt test --select test_mrt_core_customers_email_validation --debug

The --debug flag shows the full generated SQL, including the CTEs dbt creates for your mocked data. This is invaluable for diagnosing:

The Build-First Requirement

Unit tests need their upstream models’ schemas to exist in the database. If you’re running unit tests on a fresh environment (like a new CI runner), you’ll get “Not able to get columns for unit test” errors.

The fix: build upstream models first using --empty:

Terminal window
# Create schema-only versions of all upstream models
dbt run --select +test_type:unit --empty
# Now run unit tests
dbt test --select test_type:unit

The +test_type:unit selector (note the + prefix) selects all models upstream of models that have unit tests. The --empty flag builds tables with correct schemas but zero rows, which is cheap and fast.

This two-step pattern — build empty, then test — is the standard approach for CI/CD pipelines.

Common Selector Combinations

GoalCommand
All unit testsdbt test --select test_type:unit
All data testsdbt test --select test_type:data
Unit tests for one modeldbt test --select model_name,test_type:unit
Critical unit tests onlydbt test --select tag:critical,test_type:unit
One specific testdbt test --select test_name
Build without unit testsdbt build --exclude-resource-type unit_test
Build upstream schemas for testsdbt run --select +test_type:unit --empty

These cover 95% of daily usage. The selector syntax is composable — you can combine model names, tags, test types, and graph operators (+ for upstream/downstream) to target exactly the tests you need.