導入
この記事は ノバセル 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 をぜひご活用ください!
ここまでお読みいただきありがとうございました!