Model dbt yang berhasil dibangun belum tentu benar isinya, misalnya kunci yang kembar, nilai kosong pada kolom wajib, atau status yang tidak dikenali. Topik ini membahas pengujian schema dbt, yaitu pengujian generik yang dideklarasikan pada schema.yml dengan aturan unique, not_null, accepted_values, dan relationships. Pembahasan dilanjutkan dengan situs dokumentasi yang disusun perintah dbt docs generate. Aturan yang sama dievaluasi sungguhan pada data kecil lewat simulasi DuckDB, sehingga laporan lulus dan gagalnya terlihat tanpa memasang dbt Core. Proyek yang dipakai melanjutkan proyek analitik_pesanan pada topik dasar dbt.
Pengujian schema di schema.yml#
Pengujian schema (schema test) adalah pengujian generik yang dideklarasikan per kolom pada berkas schema.yml, dan dbt mengompilasinya menjadi SELECT yang menghitung baris pelanggaran. Empat pengujian generik yang paling sering dipakai adalah unique yang menolak nilai kembar, not_null yang menolak nilai kosong, accepted_values yang menolak nilai di luar daftar, dan relationships yang menolak nilai yang tidak ditemukan pada kolom tabel acuannya. Satu deklarasi berlaku untuk seluruh baris model, tanpa perulangan yang ditulis manual.
Karena bentuknya sama, hasilnya juga seragam. Pengujian lulus bila SELECT penghitungnya tidak mengembalikan baris apa pun, dan gagal bila ada satu baris pelanggaran saja. Tabel berikut merangkum makna keempat aturan beserta contoh kelalaian yang tertangkap.
| Pengujian | Aturan yang ditegakkan | Kelalaian yang tertangkap |
|---|---|---|
| unique | nilai pada kolom tidak boleh kembar | kunci baris yang ganda |
| not_null | nilai pada kolom wajib terisi | baris tanpa kunci yang lolos muat |
| accepted_values | nilai wajib termasuk daftar yang ditetapkan | kode baru dari sumber yang tidak diakui |
| relationships | nilai wajib ada pada kolom tabel acuan | rujukan yang menggantung ke baris hilang |
version: 2
models:
- name: stg_pesanan
description: "Baris pesanan yang siap dipakai model lain."
columns:
- name: id_pesanan
description: "Kunci pesanan dari sistem sumber."
data_tests:
- unique
- not_null
- name: id_pelanggan
description: "Kunci pelanggan yang wajib ada di tabel acuannya."
data_tests:
- not_null
- relationships:
arguments:
to: source('operasional', 'pelanggan')
field: id
- name: status
description: "Status pesanan hasil normalisasi."
data_tests:
- not_null
- accepted_values:
arguments:
values: ['BARU', 'SELESAI', 'DIBATALKAN']Kolom id_pesanan diuji dengan unique sekaligus not_null karena statusnya sebagai kunci baris. Kolom id_pelanggan merujuk tabel acuan lewat pengujian relationships yang menunjuk sumber operasional.pelanggan, persis aturan konsistensi yang dihitung secara manual pada topik dimensi kualitas. Pengujian relationships sengaja melewati nilai kosong sebagaimana kunci asing pada basis data, sehingga kelalaian itu ditangkap oleh not_null yang dinyatakan pada kolom yang sama. Daftar accepted_values pada kolom status ditulis eksplisit, sehingga kode status baru dari sumber terlihat sebagai kegagalan pengujian, bukan sebagai baris yang lewat diam-diam.
Menjalankan dbt test dan simulasi aturannya#
Perintah dbt test menjalankan seluruh pengujian yang terdaftar pada proyek dan menampilkan hasilnya per pengujian. Perintah itu berakhir dengan status gagal bila ada pengujian yang merah, sehingga orkestrator yang memanggilnya dapat menghentikan tahap berikutnya. Pengujian pada satu model saja dijalankan dengan argumen --select, cara yang lazim dipakai saat satu model sedang disunting.
# tidak-dijalankan
# dijalankan dari folder proyek setelah dbt Core terpasang
dbt test # menjalankan seluruh pengujian pada proyek
dbt test --select stg_pesanan # menjalankan pengujian satu model sajaKeluaran perintah itu berupa daftar nama pengujian dengan penanda lulus atau gagal per barisnya, ditutup ringkasan jumlahnya. Karena dbt Core tidak terpasang pada lingkungan kerja jalur ini, laporan yang menyerupainya dihasilkan oleh simulasi berikut. Skrip uji-schema-simulasi.py menanamkan pelanggaran pada enam baris stg_pesanan, lalu menilai aturan schema.yml yang sama dengan SELECT penghitung pelanggaran pada DuckDB.
"""Simulasi pengujian schema dbt pada data kecil dengan DuckDB.
Aturan yang dievaluasi sama dengan schema.yml, yaitu unique, not_null,
relationships, dan accepted_values. dbt mengompilasi setiap pengujian
menjadi SELECT yang menghitung pelanggaran, dan pola yang sama dijalankan
di sini secara eksplisit agar laporan lulus-gagalnya terlihat.
"""
import duckdb
kon = duckdb.connect()
# model stg_pesanan dengan pelanggaran yang ditanamkan
kon.execute(
"""
create table stg_pesanan as
select * from (values
(1, 'C01', 'BARU'),
(2, 'C02', 'BARU'),
(3, 'C01', 'SELESAI'),
(3, 'C01', 'SELESAI'),
(4, 'C99', 'DIKEMBALIKAN'),
(5, null, 'BARU')
) as t(id_pesanan, id_pelanggan, status)
"""
)
# sumber acuan untuk pengujian relationships
kon.execute(
"""
create table pelanggan as
select * from (values ('C01'), ('C02'), ('C03')) as t(id)
"""
)
# setiap butir berupa nama pengujian di schema.yml beserta SELECT-nya
PENGUJIAN = [
("unique_stg_pesanan_id_pesanan",
"""
select count(*) from (
select id_pesanan from stg_pesanan
group by id_pesanan having count(*) > 1
)
"""),
("not_null_stg_pesanan_id_pesanan",
"select count(*) from stg_pesanan where id_pesanan is null"),
("not_null_stg_pesanan_id_pelanggan",
"select count(*) from stg_pesanan where id_pelanggan is null"),
("relationships_stg_pesanan_id_pelanggan",
"""
select count(*) from stg_pesanan as s
where s.id_pelanggan is not null
and not exists (
select 1 from pelanggan as p where p.id = s.id_pelanggan
)
"""),
("not_null_stg_pesanan_status",
"select count(*) from stg_pesanan where status is null"),
("accepted_values_stg_pesanan_status",
"""
select count(*) from stg_pesanan
where status is not null
and status not in ('BARU', 'SELESAI', 'DIBATALKAN')
"""),
]
print("Simulasi pengujian schema dbt pada 6 baris stg_pesanan")
print("Aturan sama dengan schema.yml, dievaluasi sebagai SELECT penghitung pelanggaran.")
print()
jumlah_gagal = 0
for nama, sql in PENGUJIAN:
pelanggaran = kon.execute(sql).fetchone()[0]
status = "PASS" if pelanggaran == 0 else "FAIL"
if pelanggaran > 0:
jumlah_gagal += 1
print(f"{status:<4} {nama:<40} ({pelanggaran} pelanggaran)")
print()
print(f"selesai: {len(PENGUJIAN)} pengujian, "
f"{len(PENGUJIAN) - jumlah_gagal} lulus, {jumlah_gagal} gagal")Simulasi pengujian schema dbt pada 6 baris stg_pesanan
Aturan sama dengan schema.yml, dievaluasi sebagai SELECT penghitung pelanggaran.
FAIL unique_stg_pesanan_id_pesanan (1 pelanggaran)
PASS not_null_stg_pesanan_id_pesanan (0 pelanggaran)
FAIL not_null_stg_pesanan_id_pelanggan (1 pelanggaran)
FAIL relationships_stg_pesanan_id_pelanggan (1 pelanggaran)
PASS not_null_stg_pesanan_status (0 pelanggaran)
FAIL accepted_values_stg_pesanan_status (1 pelanggaran)
selesai: 6 pengujian, 2 lulus, 4 gagalKeluaran simulasi memperlihatkan empat kegagalan yang masing-masing terikat satu aturan. Pengujian unique menangkap id 3 yang kembar, not_null menangkap id_pelanggan yang kosong, relationships menangkap C99 yang tidak ditemukan pada tabel acuan, sedangkan accepted_values menangkap status DIKEMBALIKAN yang belum terdaftar. dbt yang sesungguhnya menampilkan pesan kegagalan berisi nama pengujian dan berkas YAML asalnya, kemudian berakhir dengan status gagal, sehingga tahap berikutnya dapat dihentikan secara otomatis.
Dokumentasi yang dihasilkan dbt#
Perintah dbt docs generate menyusun situs dokumentasi dari keadaan proyek terakhir, berisi deskripsi setiap model dan kolom, konfigurasi materialisasinya, serta graf DAG yang dapat dijelajahi. Isi deskripsinya diambil dari berkas YAML yang sama dengan tempat pengujian dinyatakan, sehingga schema.yml dan sources.yml sekaligus menjadi sumber dokumentasi. Situsnya disajikan secara lokal oleh dbt docs serve dan dibuka pada browser.
# tidak-dijalankan
# menyusun dokumentasi dari proyek, lalu menyajikannya secara lokal
dbt docs generate
dbt docs serveSalah satu tampilan penting pada situs dokumentasi itu adalah graf dependensi proyek. Pada proyek analitik_pesanan yang dipakai sepanjang modul ini, DAG-nya terdiri atas satu sumber, satu model staging, dan satu model akhir, dengan pengujian schema menempel pada model staging.
Dokumentasi yang lahir dari berkas yang sama dengan kode membuatnya tidak pernah usang. Setiap model baru yang diberi description langsung muncul pada generate berikutnya, dan setiap pengujian yang dinyatakan ikut tampak pada DAG proyeknya. Karena itu, schema.yml dipelihara sebagai berkas dokumentasi, bukan sekadar daftar aturan pengujian.
Kesalahan umum#
- Memperlakukan pengujian schema sebagai pengganti seluruh pengujian data. Penyebabnya, empat aturan generik mudah ditambahkan sehingga proyek terasa lengkap. Akibatnya, logika antarkolom yang keliru tetap lulus, misalnya total yang dihitung dari kolom yang salah. Perbaikannya, tambahkan pengujian singular berbentuk berkas SQL pada folder tests untuk aturan yang melibatkan lebih dari satu kolom.
- Membiarkan kegagalan pengujian yang berulang. Penyebabnya, aturan yang ternyata terlalu ketat tidak pernah diubah, sehingga pengujian merah menjadi pemandangan harian. Akibatnya, kegagalan baru tenggelam di antara kegagalan lama dan tidak ada yang memeriksanya. Perbaikannya, perbaiki data di sumbernya atau ubah aturannya secara sadar, lalu pastikan daftar accepted_values mengikuti nilai yang memang sah.
- Menulis description yang kosong pada schema.yml. Penyebabnya, pekerjaan dianggap selesai begitu aturan pengujinya tercantum. Akibatnya, situs dokumentasi memuat model tanpa penjelasan, dan pembaca dokumentasi menebak sendiri makna setiap kolomnya. Perbaikannya, isi description singkat untuk setiap model dan kolom yang diuji, sebagaimana schema.yml pada topik ini.
Ringkasan#
- Pengujian schema dideklarasikan per kolom pada schema.yml, dan dbt mengompilasi setiap aturannya menjadi SELECT yang menghitung baris pelanggaran.
- Perintah dbt test menampilkan laporan lulus-gagal per pengujian, dan status gagalnya dapat menghentikan tahap berikutnya pada pipeline.
- Perintah dbt docs generate menyusun situs dokumentasi berisi deskripsi dan graf DAG yang bersumber dari berkas YAML yang sama dengan pengujian.
Referensi#
- Data tests property — dbt Developer Hub — Dokumentasi kunci data_tests beserta empat pengujian generik bawaan dbt.
- Documentation — dbt Developer Hub — Dokumentasi situs dbt docs yang disusun perintah dbt docs generate.
- Upgrading to v1.8 — dbt Developer Hub — Catatan penggantian nama kunci tests menjadi data_tests beserta dukungan lamanya.