adding-dbt-unit-test
上流モデルの入力をモックし、期待される出力を検証するユニットテストのYAML定義を作成します。dbtモデルにユニットテストを追加したい場合や、dbtでテスト駆動開発(TDD)を実践する際に活用できます。
description の原文を見る
Creates unit test YAML definitions that mock upstream model inputs and validate expected outputs. Use when adding unit tests for a dbt model or practicing test-driven development (TDD) in dbt.
SKILL.md 本文
dbt モデルのユニットテストを追加
追加リソース
仕様リファレンス- ユニットテストのすべての必須および オプションの YAML キー例- 複数の形式(dict、csv、sql)にわたるユニットテストの例インクリメンタルモデル- インクリメンタルモデルのユニットテストエフェメラル依存関係- エフェメラルモデルに依存するモデルのユニットテスト特別なケースオーバーライド- 内省マクロ、プロジェクト変数、環境変数バージョン付きモデル- バージョン付き SQL モデルのユニットテストBigQuery 注意事項- BigQuery 固有の注意事項BigQuery データ型- BigQuery データ型の処理Postgres データ型- Postgres データ型の処理Redshift 注意事項- Redshift 固有の注意事項Redshift データ型- Redshift データ型の処理Snowflake データ型- Snowflake データ型の処理Spark データ型- Spark データ型の処理
dbt のユニットテストとは
dbt ユニットテストは、本番環境での実体化の前に静的入力に対する SQL モデリングロジックを検証します。モデルのユニットテストが失敗した場合、dbt はそのモデルを実体化しません。
使用時機
モデルをユニットテストする必要があります:
- モデルの意図した機能のためのモデル入力出力シナリオを追加する場合、およびモデルロジックが後で変更された場合の回帰を防ぐため。
- 既存の dbt モデルのバグレポートに対してバグ修正が解決することを確認する場合。
その他の例:
- SQL に複雑なロジックが含まれている場合:
- 正規表現
- 日付計算
- ウィンドウ関数
- 多くの
when句があるcase whenステートメント - 切り捨て
- 複雑な結合(複数の結合、自己結合、または自明でない条件を持つ結合)
- 入力データを処理するカスタムロジックを記述している場合、関数作成に類似している場合。
- 過去にバグレポートがあったロジック。
- 実際のデータではまだ見られていないが、正しく処理していることを確認したいエッジケース。
- 変換ロジックをリファクタリングする前(特に大規模なリファクタリングの場合)。
- 高い「重要性」を持つモデル(公開モデル、契約されたモデル、またはエクスポーズの直上流モデル)。
使用しない場合
ユニットテストを作成することをお勧めしないケース:
- ウェアハウスプロバイダーによって徹底的にテストされている組み込み関数。予期しない問題が発生した場合、それは基盤となるデータの問題ではなく、関数自体の問題である可能性が高いです。したがって、ユニットテスト内のフィクスチャデータは有用な情報を提供しません。
min()など一般的な SQL 仕様関数。
一般的な形式
dbt ユニットテストは、モデル、与えられた入力、および期待される出力(モデル入力出力)の 3 つを使用します:
model- このモデルを構築する場合given入力 - ソース、シード、およびモデルのセットを前提条件として与える場合expect出力 - 後提条件としてモデルのこの行コンテンツを期待する場合
ワークフロー
1. テストするモデルを選択
説明不要です -- タイトルがすべてを物語っています!
2. 入力をモック
- モデルが依存するノードごとに入力を作成します。
- 使用する必要があるモックデータを指定します。
- デフォルト(YAML
dict)と異なる場合はformatを指定します。- どの
formatを使用するかは、以下の「ユニットテストのデータformat」セクションを参照してください。
- どの
- モックデータは、このテストケース内で使用される列のサブセットのみを含む必要があります。
ヒント: dbt show を使用して、上流モデルまたはソースからの既存データを探索します。これにより、現実的な入力構造を理解できます。ただし、常にサンプルデータをサニタイズして、機密情報または PII をユニットテストフィクスチャで使用する前に削除してください。
# 上流モデルデータをプレビュー
dbt show --select upstream_model --limit 5
3. 出力をモック
- これらの入力が与えられた場合にモデルが作成することを期待するデータを指定します。
- デフォルト(YAML
dict)と異なる場合はformatを指定します。- どの
formatを使用するかは、以下の「ユニットテストのデータformat」セクションを参照してください。
- どの
- モックデータは、このテストケース内で使用される列のサブセットのみを含む必要があります。
4. ユニットテストを実行する前に上流モデルが存在することを確認
ユニットテストを実行する前に、直接の親モデルがウェアハウスに存在する必要があります。 ユニットテストをスタンドアロンで実行する前(dbt test)に、上流モデルがすでに存在することを確認してください:
# 上流モデルがウェアハウスに存在するかどうかを確認
dbt list --select +my_model --exclude my_model --resource-type model
# dbt show または SQL クライアント経由でウェアハウスにテーブル/ビューが実際に存在することを確認
dbt show --select upstream_model --limit 1
上流モデルが存在しない、または存在しているが修正されて更新されていない場合は、--empty を使用してスキーマのみのバージョンを作成し、構築します:
# 上流モデルを安く構築します(スキーマのみ、データは読み込まない)
dbt run --select +my_model --exclude my_model --empty
警告:
--emptyは既存モデルをスキーマのみ(ゼロ行)バージョンで上書きします。モデルがまだ存在しないとき、またはスキーマ変更を適用する必要があるときにのみ使用してください。上流モデルに保存したいデータが含まれている場合は使用しないでください — そのデータが削除されます。
dbt build --select my_model(推奨)を使用している場合はこのステップをスキップしてください — ユニットテストを含む完全なパイプラインを処理します。
最小限のユニットテスト
このモデルがあるとします:
-- models/hello_world.sql
select 'world' as hello
そのモデルの最小限のユニットテスト:
# models/_properties.yml
unit_tests:
- name: test_hello_world
# テストする変換は常に 1 つだけ
model: hello_world
# 今回は入力は不要です!
# ほとんどのユニットテストは入力を持ちます -- 以下の「実世界の例」セクションを参照してください
given: []
# 期待される出力は 0 行以上を持つことができます
expect:
rows:
- {hello: world}
ユニットテストの実行
hello_world モデルのユニットテストを実行し、モデルを構築し、データテストを実行します:
dbt build --select hello_world
これはウェアハウスのコストを節約します。ユニットテストが正常にパスした場合にのみモデルが実体化され、データテストに進むためです。
または、モデルを構築またはデータテストを実行せずにユニットテストのみを実行します:
dbt test --select "hello_world,test_type:unit"
または名前で特定のユニットテストを選択します:
dbt test --select test_is_valid_email_address
本番ビルドからユニットテストを除外
dbt Labs は、開発環境または CI 環境でのみユニットテストを実行することを強くお勧めします。ユニットテストの入力は静的であるため、本番環境で追加の計算サイクルを実行する必要はありません。テスト駆動型アプローチで開発を行うときと、変更が破らないことを確認するための CI に使用してください。
--resource-type フラグ --exclude-resource-type または DBT_EXCLUDE_RESOURCE_TYPES 環境変数を使用して、本番ビルドからユニットテストを除外し、計算を保存します。
より現実的な例
unit_tests:
- name: test_order_items_count_drink_items_with_zero_drinks
description: >
シナリオ: 飲み物なしの注文
`order_items_summary` テーブルが構築されるとき
食べ物アイテムが 1 つだけの注文が与えられたとき
飲み物アイテムのカウントは 0 です
# モデル
model: order_items_summary
# 入力
given:
- input: ref('order_items')
rows:
- {
order_id: 76,
order_item_id: 3,
is_drink_item: false,
}
- input: ref('stg_orders')
rows:
- { order_id: 76 }
# 出力
expect:
rows:
- {
order_id: 76,
count_drink_items: 0,
}
より多くのユニットテストの例については、references/examples.md を参照してください。
サポートされているおよびサポートされていないシナリオ
- dbt は SQL モデルのユニットテストのみをサポートしています。
- Python モデルのユニットテストはサポートされていません。
- スナップショット、シード、ソース、分析などの非モデルノードのユニットテストはサポートされていません。
- dbt は、現在のプロジェクト内のモデルへのユニットテスト追加のみをサポートしています。
- クロスプロジェクトモデルまたはパッケージからインポートされたモデルのユニットテストはサポートされていません。
- dbt は、
materialized view実体化を使用するモデルのユニットテストをサポートしていません。 - dbt は、再帰的 SQL を使用するモデルのユニットテストをサポートしていません。
- dbt は、内省クエリを使用するモデルのユニットテストをサポートしていません。
- dbt は、インクリメンタルモデルの挿入/マージ後のデータベーステーブルの最終状態に対する
expect出力をサポートしていません。 - dbt は、インクリメンタルモデルのマージ/挿入内容に対する
expect出力をサポートしています。
知っておくと便利
- ユニットテストは、
model-pathsディレクトリ(デフォルトではmodels/)の YAML ファイルで定義する必要があります。 - ユニットテストのフィクスチャファイルは、
test-pathsディレクトリ(デフォルトではtests/fixtures)の SQL または CSV ファイルで定義する必要があります。 - すべての
refまたはsourceモデル参照をユニットテスト設定にinputとして含めることで、コンパイル中の「ノードが見つかりません」エラーを回避できます。 - モデルに複数のバージョンがある場合、デフォルトではユニットテストはモデルのすべてのバージョンで実行されます。
- エフェメラルモデルに依存するモデルのユニットテストを実行する場合は、エフェメラルモデル入力に
format: sqlを使用する必要があります。 joinロジックのユニットテストを実行するためにはモデル内のテーブル名をエイリアスする必要があります。
ユニットテスト指定用の YAML
- ユニットテストの YAML 定義内のすべての必須およびオプションキーについては、
references/spec.mdを参照してください。
ユニットテストの入力
ユニットテストで input を使用して、テスト用の特定のモデルまたはソースを参照します:
input:の場合、refまたはsource呼び出しを表す文字列を使用します:ref('my_model')またはref('my_model', v='2')またはref('dougs_project', 'users')source('source_schema', 'source_name')
- シード入力の場合:
- シードの入力を指定しない場合、シードの CSV ファイルそのものを入力として使用します。
- シードの入力を指定した場合、その入力を代わりに使用します。
- 行を空のリスト
rows: []に設定して「空の」入力を使用します- これは、モデルが
refまたはsource依存関係を持っているが、その値がこの特定のユニットテストに無関係な場合に便利です。ただし、その入力への結合がモデルに行をドロップさせる可能性がある場合は注意してください!
- これは、モデルが
models/schema.yml
unit_tests:
- name: test_is_valid_email_address # これはテストの一意な名前です
model: dim_customers # ユニットテストを行うモデルの名前
given: # 入力のモックデータ
- input: ref('stg_customers')
rows:
- {email: cool@example.com, email_top_level_domain: example.com}
- {email: cool@unknown.com, email_top_level_domain: unknown.com}
- {email: badgmail.com, email_top_level_domain: gmail.com}
- {email: missingdot@gmailcom, email_top_level_domain: gmail.com}
- input: ref('top_level_email_domains')
rows:
- {tld: example.com}
- {tld: gmail.com}
- input: ref('irrelevant_dependency') # 認識する必要があるが、データが不要な依存関係
rows: []
...
ユニットテストのデータ format
dict はデフォルトフォーマットです — 常にここから始めます
別のフォーマットを使用する特定の理由がない限り、dict(インライン YAML)を使用します。format: を省略した場合のデフォルトです。
given:
- input: ref('orders')
# format: キーは不要です — dict がデフォルトです
rows:
- {order_id: 1, status: completed, amount: 100}
- {order_id: 2, status: pending, amount: 50}
format の選択方法
dict を使用(デフォルト) | sql を使用 | csv を使用 |
|---|---|---|
| その他すべて — これが出発点です | モデルがエフェメラルモデルに依存 | 外部フィクスチャファイルを使用 |
| dict/csv でサポートされていない列データ型 | dict でサポートされていない列データ型 | |
| サポートされていない型を持つ外部フィクスチャファイル |
重要な sql 注釈: sql フォーマットではモックデータ内のすべての列を指定する必要があります。dict と csv はテストに関連する列のみが必要です — より簡潔です。
重要な sql 要件: モデルの ref() または source() 入力のいずれかがエフェメラルモデルである場合、それらの入力に対して sql フォーマットを使用する必要があります。dict と csv は失敗します。
dbt はユニットテスト内のモックデータに対して 3 つのフォーマットをサポートしています:
dict(デフォルト): インライン YAML 辞書値。csv: インライン CSV 値または CSV ファイル。sql: インライン SQL クエリまたは SQL ファイル。
各フォーマットの例については、references/examples.md を参照してください。
注釈:
sqlフォーマットではすべての列のモックデータを指定する必要がありますが、dictとcsvではサブセットのみを指定できます。- エフェメラルモデルに依存するモデルのユニットテストを実行できるのは
sqlフォーマットのみです --dictとcsvはその場合は使用できません。 - Jinja をサポートするフォーマットはありません。
フィクスチャファイル
dict フォーマットはインライン YAML モックデータのみをサポートしていますが、csv または sql をインラインまたは別のフィクスチャファイルで使用することもできます。フィクスチャファイルを test-paths 内の fixtures サブディレクトリに保存します。例えば、tests/fixtures/my_unit_test_fixture.sql。
dict または csv フォーマットを使用する場合、関連する列のモックデータのみを定義する必要があります。これにより、簡潔で具体的なユニットテストを作成できます。sql フォーマットではすべての列を定義する必要があります。
特別なケース
- インクリメンタルモデルのユニットテスト。
references/special-cases-incremental-model.mdを参照してください。 - エフェメラルモデルに依存するモデルのユニットテスト。
references/special-cases-ephemeral-dependency.mdを参照してください。 - 内省マクロ、プロジェクト変数、または環境変数に依存するモデルのユニットテスト。
references/special-cases-special-case-overrides.mdを参照してください。 - バージョン付き SQL モデルのユニットテスト。
references/special-cases-versioned-model.mdを参照してください。
プラットフォーム/アダプター固有の注意事項
(Redshift、BigQuery など)に実装する場合は、プラットフォーム固有の詳細が必要です。データベースの注意事項ファイルを読みます(存在する場合):
references/warehouse-bigquery-caveats.mdreferences/warehouse-redshift-caveats.md
プラットフォーム/アダプター固有のデータ型
ユニットテストは、データ型自体ではなく、期待値をテストするために設計されています。dbt は提供する値を取得し、入出力モデルから推測されるデータ型にキャストしようとします。
ユニットテスト YAML 定義で入出力値を指定する方法は、データウェアハウス全体でほぼ一貫していますが、より複雑なデータ型には多少のバリエーションがあります。
データベースのデータ型ファイルを読みます:
references/warehouse-bigquery-data-types.mdreferences/warehouse-postgres-data-types.mdreferences/warehouse-redshift-data-types.mdreferences/warehouse-snowflake-data-types.mdreferences/warehouse-spark-data-types.md
ユニットテストの無効化
デフォルトでは、指定されたすべてのユニットテストが有効で、--select フラグに従って含まれます。
ユニットテストが実行されないようにするには、以下を設定します:
config:
enabled: false
ユニットテストが不正確に失敗していて、修正されるまで無効化する必要がある場合に便利です。
ユニットテストが失敗した場合
ユニットテストが失敗すると、「実際が期待と異なります」というログメッセージが表示され、2 つの間の「データ差分」が表示されます:
actual differs from expected:
@@ ,email ,is_valid_email_address
→ ,cool@example.com,True→False
,cool@unknown.com,False
ユニットテストが失敗した場合、主に 2 つの可能性があります:
- ユニットテストの構築方法にエラーがありました(偽陽性)
- モデルにバグがあります(真陽性)
どちらか一方を判定するには専門知識が必要です。
--empty フラグ
ユニットテストを実行する前に、ユニットテストを実行するモデルの直接の親がウェアハウスに存在する必要があります。run および build コマンドは、スキーマのみのドライランを構築するための --empty フラグをサポートしています。--empty フラグは ref とソースを 0 行に制限します。dbt はモデル SQL をターゲットデータウェアハウスに対して実行しますが、入力データの高価な読み取りを避けます。これは依存関係を検証し、モデルが正常に構築されることを確保します。
--empty フラグを使用して、モデルの空のバージョンを構築してウェアハウスのコストを節約します。
dbt run --select "stg_customers top_level_email_domains" --empty
一般的な間違い
| 間違い | 修正 |
|---|---|
| 組み込み関数を使用した単純な SQL をテスト | 複雑なロジックのみをユニットテスト: 正規表現、日付計算、ウィンドウ関数、マルチ条件 case ステートメント |
| 入力データのすべての列をモック | テストケースに関連する列のみを含める |
dict が機能する場合に sql フォーマットを使用 | dict(最も読みやすい)を優先し、必要な場合のみ csv または sql にフォールバック |
ref または source の input がない | 「ノードが見つかりません」エラーを回避するためにすべてのモデル依存関係を含める |
| Python モデルまたはスナップショットをテスト | ユニットテストは SQL モデルのみをサポート |
ライセンス: Apache-2.0(寛容ライセンスのため全文を引用しています) · 原本リポジトリ
詳細情報
- 作者
- dbt-labs
- ライセンス
- Apache-2.0
- 最終更新
- 不明
Source: https://github.com/dbt-labs/dbt-agent-skills / ライセンス: Apache-2.0
関連スキル
agent-browser
AI エージェント向けのブラウザ自動化 CLI です。ウェブサイトとの対話が必要な場合に使用します。ページ遷移、フォーム入力、ボタンクリック、スクリーンショット取得、データ抽出、ウェブアプリのテスト、ブラウザ操作の自動化など、あらゆるブラウザタスクに対応できます。「ウェブサイトを開く」「フォームに記入する」「ボタンをクリックする」「スクリーンショットを取得する」「ページからデータを抽出する」「このウェブアプリをテストする」「サイトにログインする」「ブラウザ操作を自動化する」といった要求や、プログラマティックなウェブ操作が必要なタスクで起動します。
anyskill
AnySkill — あなたのプライベート・スキルクラウド。GitHubを基盤としたリポジトリからエージェントスキルを管理、同期、動的にロードできます。自然言語でクラウドスキルを検索し、オンデマンドでプロンプトを自動ロード、カスタムスキルのアップロードと共有、スキルバンドルの一括インストールが可能です。OpenClaw、Antigravity、Claude Code、Cursorに対応しています。
engram
AIエージェント向けの永続的なメモリシステムです。バグ修正、意思決定、発見、設定変更の後はmem_saveを使用してください。ユーザーが「覚えている」「記憶している」と言及した場合、または以前のセッションと重複する作業を開始する際はmem_searchを使用します。セッション終了前にmem_session_summaryを使用して、コンテキストを保持してください。
skyvern
AI駆動のブラウザ自動化により、任意のウェブサイトを自動化できます。フォーム入力、データ抽出、ファイルダウンロード、ログイン、複数ステップのワークフロー実行など、ユーザーがウェブサイトと連携する必要があるときに使用します。Skyvernは、LLMとコンピュータビジョンを活用して、未知のサイトも自動操作可能です。Python SDK、TypeScript SDK、REST API、MCPサーバー、またはCLIを通じて統合できます。
pinchbench
PinchBenchベンチマークを実行して、OpenClawエージェントの実世界タスクにおけるパフォーマンスを評価できます。モデルの機能テスト、モデル間の比較、ベンチマーク結果のリーダーボード提出、またはOpenClawのセットアップがカレンダー、メール、リサーチ、コーディング、複数ステップのワークフローにどの程度対応しているかを確認する際に使用します。
openui
OpenUIとOpenUI Langを使用してジェネレーティブUIアプリを構築できます。これらはLLM生成インターフェースのためのトークン効率的なオープン標準です。OpenUI、@openuidev、ジェネレーティブUI、LLMからのストリーミングUI、AI向けコンポーネントライブラリ、またはjson-render/A2UIの置き換えについて述べる際に使用します。スキャフォルディング、defineComponent、システムプロンプト、Renderer、およびOpenUI Lang出力のデバッグに対応しています。