ふくふくHukuhuku Inc.
EP.06dbt 12分公開: 2026-05-10

テストの書き方:4つの組込み + generic test + singular test

dbt の組込みテスト 4 種 (unique / not_null / accepted_values / relationships) と、自分で書く generic test / singular test の使い分け。CI で必ずブロックすべきテストの設計指針。

#dbt#testing#data quality
シェア

の真価は テストが標準で書けるところにあります。`schema.yml` に宣言を書くだけで、主キー一意性・NULL 不可・参照整合性が自動チェックされます。本記事では組込み 4 種と、独自テストの書き方を扱います。

組込みテスト 4 種

schema.yml で宣言
YAML
version: 2
models:  - name: dim_customers    description: "顧客マスタ"    columns:      - name: customer_id        description: "顧客 ID (主キー)"        tests:          - unique           # 一意          - not_null         # NULL 禁止      - name: country_code        tests:          - accepted_values:              values: ['JP', 'US', 'GB', 'DE', 'FR']      - name: tier        tests:          - accepted_values:              values: ['free', 'pro', 'enterprise']              quote: false
  - name: fct_orders    columns:      - name: customer_id        tests:          - relationships:              to: ref('dim_customers')              field: customer_id
テスト意味失敗例
`unique`重複なし同じ customer_id が 2 行ある
`not_null`NULL なしemail カラムに NULL 行がある
`accepted_values`値が許容リスト内tier に 'starter' という想定外値
`relationships`FK 整合性fct_orders.customer_id が dim_customers にない

実行と結果

テスト実行
Bash
# 全テストdbt test
# 特定モデルのテストのみdbt test --select dim_customers
# テスト失敗時に該当行を取得dbt test --select dim_customers --store-failures# → dbt_test__audit スキーマに失敗行が保存される
store-failures の威力

テスト失敗時、デフォルトでは「N 行が失敗」しか出ない。`store-failures: true` を設定すると、失敗行が に保存され、 で詳細を追える。本番監視では必須設定。

generic test (custom)

組込み 4 種で足りない検証は generic test で書く。`tests/generic/` に Jinja マクロとして定義し、複数モデルで再利用。

tests/generic/test_positive_value.sql
SQL
{% test positive_value(model, column_name) %}
SELECT *FROM {{ model }}WHERE {{ column_name }} <= 0
{% endtest %}
schema.yml で使う
YAML
models:  - name: fct_orders    columns:      - name: amount        tests:          - positive_value

singular test (専用テスト)

1 テスト = 1 SQL で、特定の業務ルールを検証したいとき。`tests/` に直接 SQL を置く。結果が 0 行なら成功、1 行以上なら失敗

tests/assert_no_future_orders.sql
SQL
-- 未来日の注文が無いことを検証SELECT  order_id,  ordered_at,  CURRENT_TIMESTAMP() AS nowFROM {{ ref('fct_orders') }}WHERE ordered_at > CURRENT_TIMESTAMP()

severity と warn/error 切り替え

重要度の制御
YAML
tests:  - unique:      severity: error          # 失敗で CI を止める  - relationships:      severity: warn           # 警告のみ、CI は通す      to: ref('dim_customers')      field: customer_id      warn_if: ">100"          # 100 行超で warn      error_if: ">10000"       # 10000 行超で error

dbt-expectations パッケージ ── 検証の幅を一気に拡張

Great Expectations 風の 数十種類の検証を提供する人気パッケージ。詳細は EP.09

dbt-expectations 例
YAML
tests:  - dbt_expectations.expect_column_values_to_be_between:      min_value: 0      max_value: 1000000
  - dbt_expectations.expect_table_row_count_to_be_between:      min_value: 100
  - dbt_expectations.expect_column_distinct_count_to_be_between:      min_value: 50      max_value: 50000

テスト設計の現実的指針

  • 主キーに必ず unique + not_null ── 例外なし。これだけで事故の半分は防げる
  • FK には relationships ── JOIN 結果が空になる事故を防止
  • accepted_values は『増えそうな enum』を避ける ── 新値追加のたびに修正が要る
  • 金額・件数の範囲 ── dbt-expectations の between で「異常な大きさ」を弾く
  • 鮮度 ── source freshness を必ず設定 (EP.03)

次の話

EP.07 ではドキュメント機能 ── schema.yml の充実と dbt docs を扱います。

シェア

この記事の感想を教えてください

あなたの 1 クリックで、本当にこの記事は更新されます。「もっと詳しく」「続編希望」が一定数集まった記事は、 ふくふくが 実際に内容を拡充したり続編記事を公開 します。 送信したリアクションはお使いのブラウザに記録され、再カウントされません。

シリーズの外も探す:

まずは、現状を聞かせてください。

要件が固まっていなくて大丈夫です。現状診断と方針提案までを無料でお手伝いします。

無料相談フォームへ hello [at] hukuhuku [dot] co [dot] jp