dbt Tests 資料品質測試
在傳統的資料開發流程中,往往缺乏自動化測試的環節。這導致我們經常是在 Dashboard 數字不對、或是 CEO 發現報表怪怪的時,才回過頭來 debug。
dbt 將軟體開發的 TDD (測試驅動開發) 概念引入資料領域。透過編寫測試,我們可以:
- 提早發現問題:在 pipeline 執行階段就攔截錯誤資料。
- 建立信任:確保提供給使用者的資料是通過驗證的。
- 防止退化 (Regression):確保新的程式碼修改不會破壞既有的邏輯。
在 dbt 中,測試的核心邏輯很簡單:只要測試的 SQL 查詢回傳任何結果 (rows),測試就判定為失敗 (Fail)。 也就是說,測試是用來「抓出錯誤資料」的。
dbt 提供了兩種類型的測試:Generic Tests 與 Singular Tests。
Generic Tests (通用測試)
Generic Tests 是 dbt 內建的標準測試模組,定義在 YAML 檔案中。包含以下四種:
unique: 檢查欄位值是否唯一 (Primary Key 檢查)。not_null: 檢查欄位值是否為非空。accepted_values: 檢查欄位值是否在允許的清單內 (如 status 只能是 active, inactive)。relationships: 檢查外鍵關聯 (Referential Integrity),確認 A 表的 key 是否存在於 B 表中。
如何設定
在 models/ 下的 YAML 檔案中 (如 schema.yml) 設定:
version: 2
models:
- name: customers
columns:
- name: id
tests:
- unique
- not_null
- name: status
tests:
- accepted_values:
values: ['active', 'inactive', 'deleted']
- name: orders
columns:
- name: customer_id
tests:
- relationships:
to: ref('customers')
field: id
Singular Tests (單一測試)
當內建的通用測試不滿足需求,你需要針對特定的業務邏輯寫測試時 (例如:訂單金額不能為負數),就可以使用 Singular Tests。
如何建立
Singular Test 本質上就是一個放在 tests/ 目錄下的 .sql 檔案。
範例:建立 tests/assert_order_amount_is_positive.sql
-- 找出金額小於 0 的異常訂單
select
order_id,
amount
from {{ ref('orders') }}
where amount < 0
如果這個 SQL 查詢回傳了任何資料 (例如發現了一筆 -100 元的訂單),dbt test 就會報錯。
執行測試
使用以下指令執行所有測試:
dbt test
dbt 會依序執行所有定義好的 Generic Tests 和 Singular Tests,並告訴你 Pass 或 Fail。
常見參數
- 選定特定 model 測試:
dbt test --select customers - 選定特定測試類型:
dbt test --select test_type:generic
總結
測試是 dbt 專案中不可或缺的一環。強烈建議為每一個 model 的 Primary Key 加上 unique 和 not_null 測試,這是一個成本極低但效益極高的最佳實踐。