Testing Shell Script dengan Bats di Linux untuk Otomasi Production
Last updated on
Target keyword: testing shell script linux
Monthly keyword cluster: linux shell scripting, bash scripting linux, testing shell script, otomasi linux production, bash best practice
Weekly intent rotation: Problem-solving + implementation playbook (MOFU/BOFU)
Kalau kamu pernah bilang, “script ini kan simpel, ngapain dites?”, lalu seminggu kemudian cron job gagal karena edge case kecil… kamu nggak sendirian.
Di banyak tim, shell script tumbuh dari satu file kecil jadi tulang punggung otomasi: backup, sinkronisasi, deploy, cleanup, sampai health check. Masalahnya, begitu script makin sering dipakai, bug kecil jadi mahal. Salah parse argumen bisa hapus file yang salah. Exit code yang kebalik bisa bikin pipeline lanjut padahal sebenarnya gagal.
Nah, di sinilah testing shell script linux jadi penting. Artikel ini bahas cara praktis ngetes shell script pakai Bats (Bash Automated Testing System) dengan gaya yang realistis buat production: gampang dijalankan di lokal, bisa dimasukin CI, dan tetap enak di-maintain.
Kenapa testing shell script wajib (bukan “nice to have”)
Banyak orang nyaman ngetes script secara manual:
- jalankan script,
- lihat output,
- kalau kelihatan benar, dianggap selesai.
Pendekatan ini oke buat eksperimen cepat, tapi rapuh untuk otomasi rutin. Ada beberapa risiko:
-
Regresi diam-diam
Perubahan kecil di fungsi A bisa ngerusak fungsi B, tapi nggak kelihatan sampai job jalan tengah malam. -
Perilaku berbeda antar environment
Lokalmu aman, tapi di server PATH beda, locale beda, atau dependensi beda versi. -
Refactor jadi menakutkan
Tanpa test, setiap perapihan kode terasa berjudi.
Dengan test otomatis, kamu punya “jaring pengaman”. Perubahan jadi lebih percaya diri dan debugging lebih cepat karena gagal di titik yang jelas.
Kalau kamu belum setup fondasi script yang aman, baca juga:
- Bash Strict Mode and Safe Automation Checklist for Linux Servers
- Shell Script Code Review Checklist Linux Teams Production
Kenalan cepat: apa itu Bats?
Bats adalah framework test untuk Bash/shell script. Konsepnya mirip unit test di bahasa lain:
- kamu bikin file test,
- tiap
@testngecek satu perilaku, - jalankan semuanya sekaligus,
- dapat hasil pass/fail yang jelas.
Contoh minimal:
@test "penjumlahan sederhana" {
result=$((2 + 3))
[ "$result" -eq 5 ]
}
Simple, tapi ini cukup untuk membangun kebiasaan test-first atau minimal test-before-merge pada workflow bash scripting linux.
Setup Bats di Linux
Ada beberapa cara install. Pilih yang paling cocok dengan environment kamu.
Opsi A: install via package manager (jika tersedia)
# Ubuntu/Debian (nama paket bisa berbeda tergantung versi)
sudo apt update
sudo apt install -y bats
Opsi B: clone repo Bats (lebih konsisten antar distro)
git clone https://github.com/bats-core/bats-core.git
cd bats-core
sudo ./install.sh /usr/local
Cek instalasi:
bats -v
Kalau versi tampil, berarti siap lanjut.
Struktur project yang rapi buat testing
Supaya enak dipelihara, hindari campur semua hal di satu file raksasa. Minimal pakai struktur ini:
project/
scripts/
backup.sh
lib.sh
test/
backup.bats
fixtures/
sample-data/
Tips penting:
- pindahkan logic reusable ke
lib.sh(fungsi-fungsi kecil), backup.shfokus orkestrasi,fixtures/isi data dummy untuk test yang repeatable.
Struktur ini bikin script lebih mudah diuji dan cocok buat tim kecil yang jalan cepat.
Contoh script yang akan kita tes
Misal kita punya script sederhana buat validasi file input sebelum diproses.
#!/usr/bin/env bash
set -euo pipefail
validate_input_file() {
local file="$1"
if [[ -z "$file" ]]; then
echo "error: file path required" >&2
return 2
fi
if [[ ! -f "$file" ]]; then
echo "error: file not found: $file" >&2
return 3
fi
if [[ ! -s "$file" ]]; then
echo "error: file is empty: $file" >&2
return 4
fi
echo "ok: input valid"
}
Simpan misalnya di scripts/lib.sh.
Menulis test Bats pertama
Sekarang kita buat test/backup.bats:
#!/usr/bin/env bats
setup() {
TMP_DIR="$(mktemp -d)"
source "${BATS_TEST_DIRNAME}/../scripts/lib.sh"
}
teardown() {
rm -rf "$TMP_DIR"
}
@test "gagal saat argumen file kosong" {
run validate_input_file ""
[ "$status" -eq 2 ]
[[ "$output" == *"file path required"* ]]
}
@test "gagal saat file tidak ditemukan" {
run validate_input_file "$TMP_DIR/not-found.txt"
[ "$status" -eq 3 ]
[[ "$output" == *"file not found"* ]]
}
@test "gagal saat file kosong" {
touch "$TMP_DIR/empty.txt"
run validate_input_file "$TMP_DIR/empty.txt"
[ "$status" -eq 4 ]
[[ "$output" == *"file is empty"* ]]
}
@test "sukses saat file valid" {
echo "hello" > "$TMP_DIR/input.txt"
run validate_input_file "$TMP_DIR/input.txt"
[ "$status" -eq 0 ]
[[ "$output" == *"ok: input valid"* ]]
}
Jalankan:
bats test/backup.bats
Kalau semua hijau, kamu baru saja punya safety net untuk fungsi kritis.
Pola test yang paling berguna untuk shell script production
Biar test kamu benar-benar kepakai, fokus ke 4 kategori ini:
1) Test exit code
Di dunia CLI/otomasi, exit code itu kontrak. Banyak pipeline bergantung ke sini.
- sukses harus
0, - error spesifik sebaiknya beda kode (misal 2, 3, 4).
2) Test output error yang actionable
Jangan cuma “failed”. Pastikan pesan error bantu user/dev ngerti masalah dan langkah berikutnya.
3) Test edge case input
Contoh:
- path kosong,
- file dengan spasi,
- file sangat kecil/empty,
- karakter khusus.
4) Test idempotensi untuk operasi aman
Kalau script boleh dijalankan berulang, pastikan run ke-2 tidak merusak state.
Untuk ini kamu bisa kombinasikan dengan panduan:
- Idempotent Shell Script: Jalankan Berkali-kali Tanpa Berantakan
- Mencegah Cron Job Tumpang Tindih di Linux dengan flock
Integrasi ke CI biar nggak lupa jalanin test
Test yang bagus tapi nggak pernah dijalankan = dekorasi.
Minimal, pasang langkah ini di pipeline CI:
# contoh step CI sederhana
bash -n scripts/*.sh
bats test/*.bats
bash -nbuat syntax check cepat,batsbuat verifikasi perilaku.
Kalau mau lebih matang, bisa tambah:
shellcheckuntuk static analysis,- matrix test untuk beberapa versi Bash.
Dengan ini, setiap PR otomatis dicek sebelum merge.
Strategi adopsi Bats bertahap (biar tim nggak kaget)
Salah satu alasan testing shell script sering ketunda adalah rasa “kebanyakan kerjaan”. Cara paling aman adalah adopsi bertahap, bukan revolusi total.
Minggu 1: pilih 1 script paling kritis (misalnya backup atau cleanup). Tambahkan test untuk 2 jalur sukses dan 2 jalur gagal. Fokus dulu ke exit code + pesan error.
Minggu 2: masukkan test ke CI dan jadikan notifikasi fail terlihat di channel tim. Jangan langsung block merge kalau tim belum siap; pakai mode observasi dulu 3–7 hari.
Minggu 3: mulai wajibkan test untuk script baru. Untuk script lama, gunakan aturan “boy scout”: setiap kali file disentuh, tambah minimal satu test.
Minggu 4 dan seterusnya: review coverage berbasis risiko, bukan jumlah test. Script yang menyentuh data produksi, proses deploy, atau credential harus punya perlindungan lebih ketat.
Dengan ritme ini, tim tetap bisa delivery cepat sambil naikin reliability secara konsisten. Nggak drama, tapi hasilnya kerasa.
Troubleshooting umum saat mulai pakai Bats
Masalah 1: source file gagal di test
Biasanya path salah karena asumsi working directory. Gunakan:
"${BATS_TEST_DIRNAME}/../scripts/lib.sh"
Jangan hardcode path relatif ke direktori tempat kamu menjalankan command.
Masalah 2: test flaky (kadang pass kadang gagal)
Penyebab umum:
- pakai file temp global yang bentrok,
- tergantung waktu/network tanpa mock,
- ada state dari test sebelumnya.
Solusi:
- selalu pakai
mktemp -ddisetup, - bersihin state di
teardown, - pisahkan test pure logic dari test integrasi.
Masalah 3: susah ngetes fungsi yang langsung exit
Refactor fungsi supaya return kode, lalu exit dilakukan di layer eksekusi utama. Ini bikin fungsi lebih testable.
Masalah 4: script terlalu besar dan sulit diuji
Pecah jadi:
- file library berisi fungsi,
- file runner/entrypoint untuk parsing argumen dan alur utama.
Ini bukan cuma soal test—ini juga ningkatin maintainability.
Checklist implementasi cepat (biar langsung jalan)
- Instal Bats di environment dev/CI
- Pisahkan logic fungsi ke file library (
lib.sh) - Buat test untuk jalur sukses + jalur gagal utama
- Verifikasi exit code dan pesan error
- Tambah test edge case input
- Integrasikan
batske pipeline CI - Jadikan test wajib sebelum merge
Kalau butuh observability lebih lanjut setelah testing, lanjut ke:
- Shell Script Observability: Logging, Metrics, Alerting Linux Production
- Debug Shell Script Linux Production: Teknik Cepat Menemukan Error
FAQ
1) Apakah Bats cocok untuk tim kecil atau solo developer?
Cocok banget. Setup-nya ringan, sintaksnya mudah, dan dampaknya besar untuk mencegah bug berulang di otomasi harian.
2) Wajib pakai Bats-core terbaru?
Disarankan, karena lebih aktif dan dokumentasinya jelas. Tapi prinsip testing-nya tetap sama: cek exit code, output, dan edge case penting.
3) Apakah semua shell script harus di-unit-test?
Nggak harus 100%. Prioritaskan script yang sering jalan, berdampak ke data, atau terhubung ke proses deploy/backup/security.
4) Bedanya test manual vs Bats apa?
Manual cepat untuk eksplorasi, Bats unggul untuk konsistensi. Bats memastikan perilaku tetap benar setiap ada perubahan kode.
Penutup
Di ekosistem otomasi linux production, shell script sering jadi komponen kritis tapi paling kurang dilindungi. Mulai dari test sederhana pakai Bats bisa langsung ningkatin keandalan pipeline kamu tanpa nambah kompleksitas berlebihan.
Kalau mau langkah paling pragmatis: pilih satu script yang paling sering bikin insiden, tulis 4–6 test inti, lalu pasang di CI. Dari situ, kamu bakal ngerasain sendiri efeknya: refactor lebih pede, bug lebih cepat ketahuan, dan jam tidur lebih aman 😄.
Komentar
Memuat komentar...
Tulis Komentar