RAKSUL TechBlog

RAKSULグループのエンジニアが技術トピックを発信するブログです

dbt v1.8から追加されたunit_testの機能、overridesの紹介

導入

この記事は ノバセル Advent Calendar 3 日目です。

こんにちは、ノバセル 24 年新卒の秦です。 テクノロジー開発部にて、データエンジニアをしています。

弊社では dbt を使っています。

dbt は v1.8 から unit_test が使えるようになりました。

今回はその unit_test の機能の 1 つである overrides について紹介したいと思います。

overrides はマクロや変数の出力を unit_test 時のみ上書きすることができる機能です。

overrides はこんな場面で使えますよ、私は overrides をこんな場面で使いましたというのを例を添えて紹介します。

紹介

例 1:dbt_utils.star を使用している時

dbt_utils.star は一部のカラムを除いた全カラムを取得できるマクロです。 色々便利なのですが、私はカラム数が変動するテーブルを unpivot したい時に便利さを感じました。 使用するクエリのイメージは以下です。

WITH  dynamic_col_table_data AS (
    SELECT
        product_id,
        day,
        {{ dbt_utils.star(from=ref('dynamic_col_table'), except=["product_id", "day"]) }}  -- 動的にカラムを取得
    FROM {{ ref('dynamic_col_table') }}
),
unpivoted_dynamic_col_table AS (
    SELECT
        product_id,
        day,
        col_name,
        col_value
    FROM dynamic_col_table_data
    UNPIVOT (
        col_value FOR col_name IN ({{ dbt_utils.star(from=ref('dynamic_col_table'), except=["product_id", "day"]) }}) -- 動的なカラムを取得しunpivotに使用
    )
)
SELECT
    *
FROM unpivoted_dynamic_col_table

ですが dbt_utils.star を使用すると unit_test が上手く動きません。 dbt_utils.star がカラム名を取得するためのテーブルを参照できないからです。 ですので以下のように unit_test では dbt_utils.star が返すカラム名を overrides してあげる必要があります。

unit_tests:
  - name: test_unpivoted_dynamic_col_table
    model: unpivoted_dynamic_col_table
    overrides:
      macros:
        dbt_utils.star: 'col1, col2, col3'  # UNPIVOT対象のカラムを指定
    given:
      - input: ref('dynamic_col_table')
        rows:
          - {product_id: 1, day: '2024-01-01', col1: 10, col2: 20, col3: 30}
          - {product_id: 2, day: '2024-01-02', col1: 15, col2: 25, col3: 35}
    expect:
      rows:
        - {product_id: 1, day: '2024-01-01', col_name: 'col1', col_value: 10}
        - {product_id: 1, day: '2024-01-01', col_name: 'col2', col_value: 20}
        - {product_id: 1, day: '2024-01-01', col_name: 'col3', col_value: 30}
        - {product_id: 2, day: '2024-01-02', col_name: 'col1', col_value: 15}
        - {product_id: 2, day: '2024-01-02', col_name: 'col2', col_value: 25}
        - {product_id: 2, day: '2024-01-02', col_name: 'col3', col_value: 35}

例 2:時刻などの実行タイミングによって変わる値を使用している時

以下のクエリのように CURRENT_TIMESTAMP など実行タイミングによって変わる値を使用している場合があります。

WITH select_future_event AS (
    SELECT
        event_id,
        event_time,
    FROM {{ ref('akashic_records') }}
    WHERE event_time > CURRENT_TIMESTAMP
)
SELECT
    event_id,
    event_status
FROM select_future_event

このような場合も overrides を使うことで上手くテストすることができます。 CURRENT_TIMESTAMP の出力を固定することで、いつテストを実行しても同じ結果を得ることができます。

ユニットテスト

unit_tests:
  - name: test_get_only_future_event
    model: future_event_model
    overrides:
      macros:
        CURRENT_TIMESTAMP: '2025-01-01 12:00:00'  # 現在時刻を固定
    given:
      - input: ref('events')
        rows:
          - {event_id: 1, event_time: '2025-01-02 12:00:00'}  # 未来の出来事
          - {event_id: 2, event_time: '2024-11-28 12:00:00'}  # 過去の出来事
    expect:
      rows:
        - {event_id: 1, event_time: '2025-01-02 12:00:00'}

最後に

この記事では unit_test の overrides 機能について紹介をしました。

overrides を使うことで、unit_test 時にマクロや変数の出力を上書きできます。

これにより、

  • dbt_util.star のようなマクロをクエリ内で使っている場合でもテストが行える。
  • 動的な値を使用しているクエリでもいつでも同じ条件でテストができる。

というメリットがあります。

unit_test をする際は overrides をぜひご活用ください!

ここまでお読みいただきありがとうございました!

参考:

docs.getdbt.com

docs.getdbt.com

docs.getdbt.com