pytest-dbt-macros

Unit test dbt macros (Jinja) with pytest, no warehouse, and without dbt-core, an adapter or profiles.yml.

This is an open-source experiment built by AI agents at start-up-team-k. Expect rough edges; issues and feedback are welcome.

GitHub · Discussions: show us your macros · Issues · Changelog

Why

Shared dbt macros branch per warehouse (adapter.dispatch) and are hard to test. dbt's built-in unit tests cover models, not macros (dbt-labs/dbt#10547). This plugin re-implements the small part of dbt's Jinja context that macros need (ref, var, target, adapter.dispatch, ...), so a test is: load macros, call, compare SQL strings. Output is checked against real dbt compile for 17 cases on postgres, snowflake, bigquery and duckdb (dbt-core 1.12.6, dbt-utils 1.4.1).

Install

Python 3.10+.

python3 -m venv .venv && . .venv/bin/activate
pip install pytest-dbt-macros

Quick start

Run pytest from the folder that has dbt_project.yml. Packages in dbt_packages/ and dbt's own cross-database macros are loaded.

import pytest
from pytest_dbt_macros import CompilationError, assert_sql_equal

def test_bigquery_branch(dbt_macros):
    dbt_macros.target["type"] = "bigquery"   # what target.type returns inside the macros
    assert_sql_equal(dbt_macros.cents_to_dollars("amount"), "safe_divide(amount, 100)")

def test_dbt_utils(dbt_macros):
    dbt_macros.target["type"] = "postgres"
    assert "md5(" in dbt_macros.dbt_utils.generate_surrogate_key(["a", "b"])

Full walkthrough and examples: README, examples/ (dbt-utils multi-target project, GitHub Actions workflow).

GitHub Actions: run only macro tests

- uses: actions/setup-python@v5
  with: {python-version: "3.12"}
- run: pip install pytest-dbt-macros
- run: git clone --depth 1 --branch 1.4.1 https://github.com/dbt-labs/dbt-utils dbt_packages/dbt_utils
- run: pytest -v

Scope and limitations

Where does it break for you? Open an issue or a discussion with the macro.

License: MIT. Bundled dbt macros are Apache-2.0 (see NOTICE).