# Calling DBT tests like a macro (plus unit tests for data tests)

**URL:** <https://discourse.getdbt.com/t/calling-dbt-tests-like-a-macro-plus-unit-tests-for-data-tests/18356>\
**Category:** Help\
**Tags:** testing, macros, dbt-core\
**Created:** [February 21, 2025, 11:54pm UTC](https://discourse.getdbt.com/t/calling-dbt-tests-like-a-macro-plus-unit-tests-for-data-tests/18356 "2025-02-21T23:54:03Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![mroy](https://sea2.discourse-cdn.com/flex020/user_avatar/discourse.getdbt.com/mroy/32/3094_2.png) [@mroy](https://discourse.getdbt.com/u/mroy)\
**Post date:** [February 21, 2025, 11:54pm UTC](https://discourse.getdbt.com/t/calling-dbt-tests-like-a-macro-plus-unit-tests-for-data-tests/18356/1 "2025-02-21T23:54:03Z")

</div>

_Note: there is an existing thread [here](https://discourse.getdbt.com/t/how-can-i-call-a-test-like-a-macro/7477), but it has no resolution other than using `dbt build` (and it is now closed)._

## Solution

_ **Edit:** _ The solution is very simple… just scroll to the bottom to see it.

## The problem I’m having

We would like to call our tests in the exact same way we can call macros today.

There is a workaround, but it would be so much simpler without a workaround.

## The context of why I’m trying to do this

For many reasons.

One of the main ones would be to test our tests (i.e. create “unit tests” for our tests, or test the SQL that they generate). And sometimes we would like to use the generated SQL code in contexts other than dbt tests, for example in the context of multi-step models (models which execute multiple queries against the same table), and we would like to execute some tests _in between_ those steps. Breaking the model up into multiple separate models is not a great workaround as it becomes more challenging to control the order of execution in combination with downstream dependencies which depend on the completion of the entire process (but only need/reference that one table), which adds unnecessary overhead.

Unfortunately, right now it doesn’t seem possible. So we must test by hand using the target folder (or query history), which is awful. We have many complex tests with large sets of parameters, and making changes to them can get very tricky without any kind of automated testing. There are too many possible combinations of parameters to possibly test everything by hand every time.

## What I’ve already tried

Calling a test like a macro simply results in this error: `'test' is undefined. This can happen when calling a macro that does not exist. Check for typos and/or install package dependencies with "dbt deps".`

## Some example code or error messages

```auto
{{ test-something(model, 'column', param=value, ...) }}
{{ something(model, 'column', param=value, ...) }}

```

## Possible Workaround

Defining all of our tests as _actual_ macros, and then wrapping the actual tests around those macro (like a proxy/facade).

But that’s pretty repetitive as it would require us to repeat the entire definition twice (so that we can call the macro in the exact same way that we can call/configure the test), and then also repeat all of the parameters again for the proxy call.

Something like this:

```auto
{% macro _test_something(model, column_name, long="", list=[], of=True, params=[], please="help", DRY=False, ...) %}
SELECT 'the test is actually defined here';
{% endmacro %}

{% test something(model, column_name, long="", list=[], of=True, params=[], please="help", DRY=False, ...) %}
  {{ _test_something(model, column_name, long, list, of, params, please, DRY, ...) }}
{% endtest %}

```

_Note that the macro cannot be called `test_something` (hence the leading underscore), as that would interfere with the name of the test:_

```auto
Compilation Error
  dbt found two macros named "test_something" in the project "wow".
   To fix this error, rename or remove one of the following macros:
      - macros/tests/test-something.sql
      - macros/tests/test-something.sql

```

---

<div class="post-metadata">

**Author:** ![mroy](https://sea2.discourse-cdn.com/flex020/user_avatar/discourse.getdbt.com/mroy/32/3094_2.png) [@mroy](https://discourse.getdbt.com/u/mroy)\
**Post date:** [February 22, 2025, 2:32am UTC](https://discourse.getdbt.com/t/calling-dbt-tests-like-a-macro-plus-unit-tests-for-data-tests/18356/2 "2025-02-22T02:32:42Z")

</div>

Well… nevermind!

We _ **can** _ actually call tests as macros already!

The key is to prefix the name of the test with `test_` (with an underscore), like `{{ test_unique(...) }}`.

🤦‍♂️

---

<div class="post-metadata">

**Author:** ![mroy](https://sea2.discourse-cdn.com/flex020/user_avatar/discourse.getdbt.com/mroy/32/3094_2.png) [@mroy](https://discourse.getdbt.com/u/mroy)\
**Post date:** [February 22, 2025, 2:58am UTC](https://discourse.getdbt.com/t/calling-dbt-tests-like-a-macro-plus-unit-tests-for-data-tests/18356/3 "2025-02-22T02:58:26Z")

</div>

Bonus: this is really, really great to unit test data tests! 🙌

Here’s a _extremely_ simplified example. You just need to create a dummy model/table, and then:

```sql
INSERT OVERWRITE INTO {{ this }}
(VALUES (1), (2)) AS t (id);

WITH test AS (
  {{ test_unique(this, 'id') }}
)
SELECT COUNT(*) AS c
FROM test
HAVING c != 0
  AND 'UNIT TEST FAILED: Expected no duplicates to be found, but some where found.';

INSERT OVERWRITE INTO {{ this }}
(VALUES (1), (1)) AS t (id);

WITH test AS (
  {{ test_unique(this, 'id') }}
)
SELECT COUNT(*) AS c
FROM test
HAVING c != 1
  AND 'UNIT TEST FAILED: Expected one duplicates to be found, but ' || c || ' where found.';

```

It’s even possible to test data tests that should produce errors by leveraging Snowflake scripting to catch the expected errors:

```sql
DECLARE
  test_failed EXCEPTION(-20001, 'TEST IS SUPPOSED TO FAIL!');
BEGIN
  {{ test_unique(this, 'column_that_does_not_exist') }};
      
  RAISE test_failed;
EXCEPTION
  WHEN statement_error THEN
    RETURN 'TEST FAILED AS EXPECTED';
END;

```

---

<div class="post-metadata">

**Author:** ![system](https://us1.discourse-cdn.com/flex020/uploads/getdbt/original/1X/a7a7ca1fe379aaf90952b0e13118a817babcd14f.png) [@system](https://discourse.getdbt.com/u/system)\
**Post date:** [March 1, 2025, 2:59am UTC](https://discourse.getdbt.com/t/calling-dbt-tests-like-a-macro-plus-unit-tests-for-data-tests/18356/4 "2025-03-01T02:59:25Z")

</div>

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.
