Menguji Langkah Pipeline dengan Assertion
Tambahkan pemeriksaan jumlah baris, assertion null, dan pengaman kolom yang diharapkan pada setiap tahap agar errors segera terlihat.
Menguji Langkah Pipeline dengan Assertion adalah pelajaran Pandas & NumPy Academy gratis di CoddyKit. Ini adalah pelajaran 3 dari 4. Kamu bisa membaca pelajaran lengkapnya di bawah secara gratis — lalu praktikkan langsung di browser dengan editor kode bawaan dan tutor AI 24/7. Ini adalah bagian dari jalur belajar Pandas & NumPy Academy, dan progresmu tersinkronisasi di web dan aplikasi CoddyKit. Kursus Pandas & NumPy Academy mencakup 4 pelajaran total.
Mengapa Menguji Tahapan Alur Data?
Alur data yang berjalan tanpa error tetap dapat menghasilkan output yang salah secara diam-diam: baris terhapus akibat filter yang keliru, kolom dikalikan dengan faktor yang salah, atau penggabungan yang menggandakan baris karena kunci penggabungan tidak unik. Satu-satunya cara untuk menemukan kegagalan diam-diam ini adalah menyisipkan assertion yang memverifikasi properti data yang diharapkan pada setiap tahap alur data. Assertion mengubah bug logika menjadi error yang jelas dan langsung terlihat.
import pandas as pd
import numpy as np
# A transform that looks correct but has a bug:
def compute_revenue_buggy(df):
# BUG: unit_price should be multiplied, not added
df['revenue'] = df['quantity'] + df['unit_price']
return df
# Without assertions, this runs silently with wrong numbers.Pemeriksaan Jumlah Baris
Setelah setiap tahap pemfilteran, pastikan dengan assertion bahwa jumlah baris yang dihasilkan berada dalam rentang yang diharapkan. Terlalu sedikit baris berarti filter terlalu ketat; terlalu banyak baris berarti penggabungan menggandakan rekaman. Nyatakan rentang yang diharapkan sebagai pecahan dari input: misalnya, tahap penghapusan nilai null seharusnya tidak pernah menghapus lebih dari 30% baris pada data yang sehat. Penjaga ini menemukan perubahan kualitas data yang tidak terduga pada sumber hulu.
def drop_nulls_guarded(df, required_cols, max_drop_fraction=0.3):
before = len(df)
result = df.dropna(subset=required_cols)
after = len(result)
drop_fraction = (before - after) / before
assert drop_fraction <= max_drop_fraction, \
f'dropna removed {drop_fraction:.1%} of rows (limit {max_drop_fraction:.1%})'
return resultPemeriksaan Keberadaan Kolom
Pastikan dengan assertion bahwa semua kolom output yang diharapkan tersedia setelah setiap fungsi transformasi. Jika tahap penggantian nama tidak sengaja menggunakan kunci yang salah, kolom yang dihasilkan akan hilang—dan error tersebut baru muncul jauh kemudian saat tahap lain mencoba menggunakannya. Assertion yang ditempatkan segera setelah transformasi menemukan masalah di sumbernya, bukan tiga tahap kemudian dengan KeyError yang membingungkan.
def compute_revenue(df):
df = df.assign(revenue=lambda d: d['quantity'] * d['unit_price'])
# Guard: check that the new column exists and is non-null
assert 'revenue' in df.columns, 'revenue column not created'
assert df['revenue'].notna().all(), 'revenue has unexpected NaNs'
return dfAssertion Rentang Nilai
Setelah menghitung kolom pendapatan, pastikan dengan assertion bahwa nilainya tidak negatif. Setelah mengurai tanggal, pastikan tanggal tersebut berada dalam rentang tahun yang diharapkan. Setelah menyandikan kategori, pastikan tidak ada kode yang tidak terduga. Setiap assertion merupakan kontrak data yang mendokumentasikan perilaku yang diharapkan dan menemukan pelanggaran sejak awal. Tuliskan sebagai assertion, bukan pernyataan print, agar assertion tersebut menimbulkan error dalam proses alur data otomatis.
def validate_computed_columns(df):
assert (df['revenue'] >= 0).all(), \
f'Negative revenue: {df[df["revenue"] < 0]["revenue"].head().tolist()}'
assert (df['quantity'] > 0).all(), \
'Non-positive quantity found'
assert df['revenue'].between(0, 1_000_000).all(), \
'Revenue out of plausible range'
print('Value range checks passed.')Penjaga Tanpa Duplikasi setelah Penggabungan
Bug data yang umum adalah penggabungan banyak-ke-banyak yang secara tidak sengaja menggandakan baris. Setelah setiap pd.merge(), pastikan dengan assertion bahwa jumlah baris sesuai harapan—biasanya tidak melebihi jumlah baris DataFrame kiri untuk penggabungan kiri. Pastikan juga bahwa kolom kunci unik jika memang seharusnya demikian, sehingga penggabungan silang yang tidak disengaja dapat segera ditemukan.
def safe_merge(left, right, on, how='left'):
before = len(left)
result = left.merge(right, on=on, how=how)
after = len(result)
if how == 'left':
assert after == before, \
f'Left join increased rows from {before} to {after} — check key uniqueness in right df'
return resultAssertion Nilai Null setelah Tahap Kritis
Kolom tertentu tidak boleh bernilai null pada titik mana pun dalam alur data. Pastikan dengan assertion bahwa df['key_col'].notna().all() terpenuhi setelah setiap tahap yang dapat secara tidak sengaja memperkenalkan nilai null—misalnya penggabungan yang gagal mencocokkan beberapa baris (sehingga menghasilkan NaN pada kolom yang digabungkan), atau pemanggilan map() yang menghasilkan NaN untuk nilai yang tidak dipetakan. Jadikan assertion ini sebagai dua baris terakhir dari setiap fungsi transformasi yang menyentuh kolom tersebut.
NOT_NULL_AFTER_TRANSFORM = ['order_id', 'revenue', 'category']
def post_transform_checks(df):
for col in NOT_NULL_AFTER_TRANSFORM:
null_count = df[col].isna().sum()
assert null_count == 0, \
f'{col}: {null_count} unexpected NaN values after transform'
print('Null checks passed.')
return dfMembangun Kumpulan Pengujian untuk Tahapan Alur Data
Tulis pengujian unit untuk setiap fungsi alur data menggunakan DataFrame kecil yang dibuat secara manual untuk mengisolasi logika yang sedang diuji. Setiap pengujian harus: menyiapkan input minimal, memanggil fungsi, lalu memastikan properti output. Menggunakan assert bawaan Python sudah cukup untuk alur data sederhana; untuk proyek yang lebih besar, gunakan pytest untuk menjalankan semua pengujian secara otomatis sebelum penerapan.
def test_compute_revenue():
test_df = pd.DataFrame({
'quantity': [2, 3],
'unit_price': [10.0, 5.0]
})
result = compute_revenue(test_df)
assert 'revenue' in result.columns
assert result['revenue'].tolist() == [20.0, 15.0]
assert result['revenue'].dtype == float
print('test_compute_revenue PASSED')
test_compute_revenue()Menguji Kasus Tepi
Pengujian yang baik tidak hanya mencakup jalur normal, tetapi juga kasus tepi: input yang seluruhnya bernilai null, DataFrame kosong, DataFrame dengan satu baris, dan kolom dengan nilai ekstrem. DataFrame kosong harus menghasilkan DataFrame kosong, bukan error. DataFrame dengan satu baris harus menghitung hasil yang benar. Uji kasus-kasus ini secara eksplisit untuk memastikan alur data menanganinya dengan baik dalam produksi saat data yang tidak biasa tiba.
def test_empty_df():
empty = pd.DataFrame({'quantity': [], 'unit_price': []})
result = compute_revenue(empty)
assert len(result) == 0, 'Empty input should produce empty output'
assert 'revenue' in result.columns, 'Revenue column should still be created'
print('test_empty_df PASSED')
def test_single_row():
single = pd.DataFrame({'quantity': [1], 'unit_price': [99.0]})
result = compute_revenue(single)
assert result['revenue'].iloc[0] == 99.0
print('test_single_row PASSED')
test_empty_df()
test_single_row()Pengujian Integrasi: Alur Data Lengkap pada Data Sampel
Selain pengujian unit pada fungsi individual, tulis sebuah pengujian integrasi yang menjalankan seluruh alur data pada sampel kecil yang mewakili data nyata. Pastikan bahwa output memiliki jumlah kolom yang diharapkan, kolom kunci bersifat unik, dan total pendapatan berada dalam rentang yang masuk akal. Pemeriksaan menyeluruh ini menemukan bug dalam interaksi antartahap yang tidak terungkap oleh pengujian unit.
def integration_test(config):
raw = extract(config)
clean = transform(raw, config)
assert set(config['required_cols']).issubset(set(clean.columns))
assert clean['order_id'].is_unique
assert (clean['revenue'] >= 0).all()
assert len(clean) > 0
print(f'Integration test PASSED. Output: {clean.shape}')
integration_test(CONFIG)Pengujian Berkelanjutan dengan pytest
Seiring bertambahnya alur data, kumpulkan semua pengujian ke dalam direktori tests/ dan jalankan dengan pytest dari baris perintah. File conftest.py dapat membuat perlengkapan bersama seperti DataFrame sampel. Integrasikan pytest ke dalam alur data CI/CD agar setiap perubahan kode secara otomatis menjalankan semua pengujian sebelum penerapan. Pengujian yang gagal akan menghentikan penerapan, sehingga kode yang rusak tidak mencapai produksi.
# tests/test_transform.py — example structure
# import pytest, pandas as pd
# from pipeline.transform import compute_revenue, drop_nulls
# @pytest.fixture
# def sample_df():
# return pd.DataFrame({'quantity': [2, 3], 'unit_price': [10.0, 5.0]})
# def test_revenue(sample_df):
# result = compute_revenue(sample_df)
# assert result['revenue'].tolist() == [20.0, 15.0]
print('Run: pytest tests/ -v to execute all pipeline tests')Assertion sebagai Dokumentasi yang Terus Diperbarui
Setiap assertion dalam alur data berfungsi sebagai penjaga sekaligus bagian dari dokumentasi: assertion menyatakan dalam bentuk yang dapat dibaca mesin seperti apa data tersebut seharusnya pada titik itu. Ketika analis baru bergabung dengan proyek dan membaca kode alur data, assertion memberi tahu mereka tentang kontrak data tanpa memerlukan dokumen spesifikasi terpisah. Perlakukan setiap assertion seperti komentar—buat pesannya cukup deskriptif agar aturan bisnis yang ditegakkannya dapat dipahami.
# These assertions document business rules as code:
assert (df['order_date'] >= pd.Timestamp('2020-01-01')).all(), \
'Company was founded 2020-01-01; no orders can predate this'
assert df['region'].isin({'North', 'South', 'East', 'West', 'Central'}).all(), \
'Only 5 sales regions are valid; new regions require config update'
print('Business rules verified as assertions.')Pemeriksaan Singkat
Uji pemahaman Anda tentang konsep Analisis Data dari pelajaran ini.
Ringkasan Pelajaran
Dalam pelajaran ini, Anda mempelajari: menyisipkan pemeriksaan jumlah baris, keberadaan kolom, rentang nilai, dan null sebagai assertion di dalam alur data, menulis pengujian unit untuk setiap fungsi transformasi dengan cakupan kasus tepi, serta menjalankan pengujian integrasi dan memperlakukan assertion sebagai dokumentasi kontrak data yang terus diperbarui. Selanjutnya, kita akan membahas penjadwalan dan pencatatan alur data untuk eksekusi harian otomatis.
Pertanyaan yang Sering Diajukan
Apakah pelajaran “Menguji Langkah Pipeline dengan Assertion” gratis?
Ya — teks lengkap “Menguji Langkah Pipeline dengan Assertion” gratis dibaca di sini di web. Untuk praktiknya secara interaktif (editor kode bawaan dan tutor AI 24/7) dan buka sisa kursus Pandas & NumPy Academy, upgrade ke CoddyKit PRO. Kursus Pandas & NumPy Academy mencakup 4 pelajaran total.
Apa yang akan aku pelajari di “Menguji Langkah Pipeline dengan Assertion”?
Tambahkan pemeriksaan jumlah baris, assertion null, dan pengaman kolom yang diharapkan pada setiap tahap agar errors segera terlihat. Kamu berlatih Pandas & NumPy Academy dengan kode praktik yang langsung kamu jalankan di browser, dan tutor AI 24/7 menjawab pertanyaanmu saat kamu mengerjakan pelajaran ini.
Apakah aku perlu pengalaman untuk memulai Pandas & NumPy Academy?
Tidak diperlukan pengalaman sebelumnya. Pandas & NumPy Academy di CoddyKit dirancang untuk pemula hingga pelajar tingkat lanjut, jadi kamu bisa memulai di sini atau dari awal dan belajar sesuai kecepatan kamu sendiri. Ini adalah pelajaran 3 dari 4.
Berapa lama pelajaran “Menguji Langkah Pipeline dengan Assertion” memakan waktu?
Sebagian besar pelajaran CoddyKit memakan waktu sekitar 5–10 menit. Setiap pelajaran ringkas dan interaktif, jadi kamu membuat kemajuan stabil dan melanjutkan dari tempat kamu tinggalkan di web dan aplikasi.
Bisakah aku menulis dan menjalankan kode dalam pelajaran Pandas & NumPy Academy ini?
Ya. Setiap pelajaran Pandas & NumPy Academy menyertakan editor kode bawaan, jadi kamu menulis dan menjalankan kode nyata langsung di browser dan mendapatkan umpan balik AI instan — tidak diperlukan penyiapan lokal.
Semua pelajaran dalam kursus ini
- Menyusun Langkah Transformasi sebagai Fungsi
- Membuat Pipeline Berparameter dengan Dict Konfigurasi
- Menguji Langkah Pipeline dengan Assertion
- Menjadwalkan dan Mencatat Proses Pipeline