
dbt-datamocktoolを使ってテスト用の入出力ファイルを用いたモデルのロジックテストをしてみた
この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
データアナリティクス事業本部のueharaです。
今回は、dbt-datamocktoolを使ってテスト用の入出力ファイル(csv)を用いたモデルのロジックテストをしてみたいと思います。
はじめに
dbtで標準で備わっているテスト機能は、ユニーク性やバリデーションといったデータそのものの品質をテストするのが主な目的であるため、基本的にはモデルのロジックをテストする際には別のパッケージが必要になります。
その中でも、今回はdbt-datamocktoolを利用してみたいと思います。
【2023/12/18 追記】
dbt-core v1.8 から単体テストが標準機能で提供されるようです。
Discussionsを眺めていると、csvファイルを使ったテストにも対応しているようです。
ディレクトリ構成
必要な部分だけ記載しますが、今回のディレクトリ構成は以下の通りです。
dbt_dev ├ models | ├ dev | | ├ my_model.sql # 今回テスト対象のモデル | | └ schema.yml | └ raw.yml # sourceを記載 ├ seeds | └ test_data | ├ test__expected_output.csv # 今回のテスト用入力ファイル | └ test__raw_input.csv # 今回のテスト用期待値の出力ファイル ├ dbt_project.yml └ package.yml
package.yml
package.ymlには、依存パッケージとして今回利用する dbt_datamocktool を記載します。
packages:
- package: mjirv/dbt_datamocktool
version: 0.3.5
dbt_project.yml
dbt_project.ymlは以下です。
version: '1.0.0'
config-version: 2
profile: 'dbt_dev'
model-paths: ["models"]
analysis-paths: ["analyses"]
test-paths: ["tests"]
seed-paths: ["seeds"]
macro-paths: ["macros"]
snapshot-paths: ["snapshots"]
clean-targets:
- "target"
- "dbt_packages"
seeds:
dbt_dev:
test_data:
+schema: test
models:
dbt_dev:
dev:
+materialized: table
dbt seed によってロードされる際、 test_data フォルダ以下のデータは test というカスタムスキーマでロードされるよう指定しています。
今回は target: dev に対して dev というスキーマを利用することを想定しているため、テストデータは dev_test というスキーマ配下にロードされることになります。
raw.yml
raw.ymlは以下です。
raw スキーマ配下に raw_input というテーブルがあることを想定します。
version: 2
sources:
- name: staging
database: dbt_dev
schema: raw
tables:
- name: raw_input
my_model.sql
今回のテスト対象のモデル my_model は、あまり面白くは無いですが以下のようにしてみました。
select
id,
data * 5 as data
from {{ source('staging', 'raw_input') }}
raw_input テーブルから id と data を取得し、 data に関してはその値を5倍にしています。
schema.yml
schema.ymlは以下です。
version: 2
models:
- name: my_model
tests:
- dbt_datamocktool.unit_test:
input_mapping:
source('staging', 'raw_input'): ref('test__raw_input')
expected_output: ref('test__expected_output')
my_model に対し、dbt_datamocktoolでのロジックテストを記載しています。
設定値に関しては、元のsourceのデータにテストデータである ref('test__raw_input') をマッピングし、期待する出力を指定しています。
テストデータのcsvファイル
入力と期待する出力のcsvファイルはそれぞれ以下の通りです。
id,data 1,10 2,20 3,30
id,data 1,50 2,100 3,150
先のロジックに従い、入力の data カラムに対し、出力の data カラムの値を5倍にしています。
実行確認
まず、依存パッケージのダウンロードのため以下のコマンドを実行します。
$ dbt deps
ダウンロードが完了したら、次にseedコマンドによりテストデータのロードを行います。
$ dbt seed
成功すると、以下の通り dev_test スキーマ配下にテストに利用するテーブルが作成されているかと思います。

ここまで準備ができたら、テストを実行してみます。
$ dbt test ... 09:18:06 1 of 1 START test dbt_datamocktool_unit_test_my_model_ref_test__expected_output___ref_test__raw_input_ [RUN] 09:18:06 1 of 1 PASS dbt_datamocktool_unit_test_my_model_ref_test__expected_output___ref_test__raw_input_ [PASS in 0.18s] 09:18:06 09:18:06 Finished running 1 test in 0 hours 0 minutes and 0.28 seconds (0.28s). 09:18:06 09:18:06 Completed successfully 09:18:06 09:18:06 Done. PASS=1 WARN=0 ERROR=0 SKIP=0 TOTAL=1
無事、入力とそれに対する期待値のテストデータを用いてテストがPASSできたことが分かります。
逆に、今度はあえてmy_modelの定義を変えて一部データがテスト結果と一致しないようにしてみます。
select
id,
case id
when 3 then data * 2
else data * 5
end as data
from {{ source('staging', 'raw_input') }}
上記は id カラムが3の時だけ data を5倍ではなく2倍にしています。
これで dbt test を実行すると、以下の通りエラーが出力されます。
$ dbt test ... 14:04:10 1 of 1 START test dbt_datamocktool_unit_test_my_model_ref_test__expected_output___ref_test__raw_input_ [RUN] 14:04:10 The test <> failed with the differences: 14:04:10 ================================================================ | id | data | in_a | in_b | | -- | ---- | ----- | ----- | | 3 | 150 | True | False | | 3 | 60 | False | True | 14:04:10 ================================================================ 14:04:10 1 of 1 FAIL 2 dbt_datamocktool_unit_test_my_model_ref_test__expected_output___ref_test__raw_input_ [FAIL 2 in 0.09s] 14:04:10 14:04:10 Finished running 1 test in 0 hours 0 minutes and 0.17 seconds (0.17s). 14:04:10 14:04:10 Completed with 1 error and 0 warnings: 14:04:10 14:04:10 Failure in test dbt_datamocktool_unit_test_my_model_ref_test__expected_output___ref_test__raw_input_ (models/dev/schema.yml) 14:04:10 Got 2 results, configured to fail if != 0 14:04:10 14:04:10 compiled Code at target/compiled/dbt_dev/models/dev/schema.yml/dbt_datamocktool_unit_test_my__ef049f60d2b7d5691e3da4484cbbf0e4.sql 14:04:10 14:04:10 Done. PASS=0 WARN=0 ERROR=1 SKIP=0 TOTAL=1
id=3 のデータが期待値と一致していないことが読み取れます。
最後に
今回は、dbt-datamocktoolを使ってテスト用の入出力ファイル(csv)を用いたモデルのロジックテストをしてみました。
参考になりましたら幸いです。








