お問い合わせ
5 分で読むことができます

【Snowflakw×dbt】dbtで実行可能な2つのunit-testを比較してみた

執筆者 TAKA 更新日時 2024年4月11日

【Snowflakw×dbt】dbtで実行可能な2つのunit-testを比較してみた

目次

みなさん初めまして!INSIGHT LAB株式会社のTAKAと申します。
私は業務で主にデータ分析基盤の構築を行っており、Snowflakeとdbt coreを使用しています。近頃、dbtがv1.8へアップグレードされ、Unit testsが使えるようになるとのことで、折角なら今現在使えるdbt-unit-testingとどう違うのか、このブログで検証してみようと思います。

Unit testsとは

そもそも、Unit testsが何かというと、作成したモデルの機能を検証するためのテストとなります。今までのdbt testは、ソースのデータ品質やモデルのアウトプットデータを検証するデータのテストがメインで、機能を検証するテストはあまり行えませんでした。そのため、今まではdbt-unit-testingというパッケージを使用することで、機能検証するためのテストを実施できましたが、v1.8からはなんとパッケージを使用せずとも、dbtの標準機能としてモデルの機能を検証するUnit testsが使用できるようになります。

検証環境

今回は以下環境で検証します。

Unit testsの検証

それでは、Unit testsを検証していきます。

1.dbt-unit-testingを使用したUnit tests

まずは、dbt-coreのインストールから行います。DWHにSnowflakeを使用するため、dbt-snowflakeをインストールします。

pip install dbt-snowflake

次に、Unit testsを実行するために、パッケージdbt-unit-testingをインストールします。パッケージをインストールするには、packages.ymlに以下コードを記載して、dbt depsコマンドでインストールします。

キャプチャ_dt_packages

ちなみに、今回Unit testsでテストするモデルは以下になります。このモデルでは3つのインプットデータを使用して、注文日の最小値や最大値を取得したり、注文ID毎の注文額を集計した後に、1つのテーブルに纏めています。

それでは、Unit testsに使用するテストを用意します。 今回はjaffle_shopのdbtプロジェクトフォルダ内のtestsフォルダに、以下テスト用の.sqlファイルを用意します。

キャプチャ_dbt_sql_input-1

上記の.sqlファイルは、Unit testsに使用するインプットデータとその期待値を表しています。インプットデータの内容は、顧客IDが'1'の顧客の2024年1月1日~5日までの注文履歴を表しており、このインプットデータを元にして、customers.sqlモデルを実行した結果、期待値として設定したデータ通りの結果となることを検証するテストとなっております。今回の期待値としては、顧客IDが'1'の初回注文日や最新注文日、注文額の合計が想定通りになっていることとなります。
それでは、1つずつ見ていきます。

1行目は、必ず指定する必要があります。

キャプチャ1

3行目では、テストしたいモデルとモデルの説明を記載します。

キャプチャ2

5行目以降で、テストに使用するインプットのモデルとテストデータを指定します。

インプットのモデル指定には、mock_ref以外にもソースを指定するmock_sourceもあり、モデル毎に指定する必要があります。テストデータは、下記のようにmock_ref(mock_source)内のselectで指定が可能で、複数行設定したい場合はunionすることが可能です。

キャプチャ_dbt_sql_input

23行目でアウトプットとなるテストの期待値をexpectとして指定できます。

キャプチャ4

ここまで準備ができれば、実際にテストを行っていきます。テストの実施には、普段通りにdbt test を使用できます。1行目でtagを指定しているため、以下のようにタグを指定してテストも行えます。

dbt test --select tag:unit-test

テストした結果が以下になります。
キャプチャ5
テストが正常終了しており、期待値通りの処理が行えていることを確認できました。ここで、stg_paymentsのテストデータを変更して、テストが失敗するパターンを実行してみます。今回はamountの値を+100します。

キャプチャ_dbt_sql_errot_plus

再度実行すると、キャプチャのようにエラーとなりました。

キャプチャ6

期待値に対して、実際にモデルを実行した結果が表示されており、エラーの原因がどこか分かりやすくなってますね。
ここまでが、dbt-unit-testingを使用したUnit testsとなります。

2.v1.8から使用できるUnit tests

続いて、v1.8から使用できるようになったUnit testsを検証していきます。
こちらでも、まずはdbt-coreのインストールから始めます。

pip install dbt-core==1.8.0b1

pip install dbt-snowflake==1.8.0b1

 

v1.8はまだベータ版のため、1.8.0の後ろにベータ版のバージョン(今回であれば、b1)を付けてインストールします。また、v1.8からの変更点として、v1.8以前まではdbt-snowflakeをインストールするだけでdbtを使えましたが、v1.8からはdbt-coreもインストールする必要があるため、注意が必要となります。

次に、v1.8で使用するテストを用意します。
v1.8以前では、パッケージをインストールしてましたが、v1.8ではインストールせずともUnit testsを使えるため、packages.ymlの記載は省略してUnit testsを記載していきます。packages.ymlの記載とdbt depsを実行する手間が省けるので、この点はv1.8の方が楽ですね。

そして、dbt-unit-testingでは.sqlファイルにコードを記載していましたが、v1.8では.ymlにテストを記載していきます。

キャプチャ_dbt_customer_test

テストの内容としてはdbt-unit-testingと同じになります。v1.8ではmacroを使用しない分、コードが少し短く、かつ、シンプルに感じました。

記載についてですが、1行目でunit_testを指定し、namedescriptionを記載します。

キャプチャ_dbt1-8-name

4行目のmodelでテストしたい対象のモデルを指定し、given以降でテストする条件を指定します。inputではインプットとなるモデル、rowsでインプットデータを設定します。

キャプチャ_dbt_18_test_input

expectで期待値を指定します。

キャプチャ8

.ymlファイルにUnit testsを記載したので、最後にdbt testを行っていきます。nameを指定しているので、test実施時にnameを指定してテストすることもできます。

dbt test --select sample_test

テストした結果が以下になります。
キャプチャ9
テストが正常終了しており、期待値通りの処理が行えていることを確認できました。ここでも、stg_paymentsのテストデータを変更して、テストが失敗するパターンを実行してみます。今回はamountの値を-100します。

キャプチャ_dbt_18_error_test

再度実行すると、キャプチャのようにエラーとなりました。
キャプチャ_dbt_18_error_result
dbt_unit_testingよりも、結果がシンプルですね。
以上がv1.8を使用したUnit testsとなります。

まとめ

dbt_unit_testingとv1.8でできるようになったUnit testsを比較してみましたが、パッケージをインストールする手間が減ったり、テストコードをシンプルに書けたりとv1.8の方が使いやすそうと感じました。ただ、dbt_unit_testingとv1.8のUnit testsも実務では使っていないので、色々使っていく中で、dbt_unit_testingの方が使いやすい場面もあるのかなとも感じました。どちらにしても、モデルの機能を検証するテストはとても有用なテストだと感じたので、これから実務にも取り入れていきたいと思います。皆さんも気になれば、ぜひ使ってみてください!

Snowflakeを体験してみませんか?

INSIGHT LABではSnowflake紹介セミナーを定期開催しています。Snowflakeの製品紹介だけでなく、デモンストレーションを通してSnowflakeのシンプルなUI操作や処理パフォーマンスの高さを体感いただけます。

詳細はこちら

TAKA

執筆者 TAKA

4 分で読むことができます。
Snowflakeの料金体系|クレジットと費用最適化のポイントをご紹介
5 分で読むことができます。
【禁断の比較?】SnowflakeとTreasure Dataを比べてみました
1 分で読むことができます。
誤ってupdateしてしまったレコードをtime travelで復元する
5 分で読むことができます。
【Snowflake】新機能「Streamlit in Snowflake」とは何者か!?
3 分で読むことができます。
AWS Lambdaを使ってSnowflakeとSFTPサーバーを連携してみた