Memakai AI untuk Menulis Test yang Berguna
Salah satu hal pertama yang saya coba begitu asisten AI mulai bisa menulis kode dengan baik adalah: suruh dia menulis test. Hasilnya cepat, rapi, dan biasanya langsung hijau saat dijalankan. Tapi setelah beberapa kali memakainya di proyek Laravel yang saya tangani sehari-hari, saya sadar ada jebakan yang mudah terlewat: test yang lolos bukan berarti test yang berguna. AI sangat pandai menulis test yang secara teknis benar tapi secara substansi kosong — dan kalau kita tidak mereview dengan sudut pandang yang tepat, kita cuma menambah angka coverage tanpa menambah jaring pengaman yang sesungguhnya.
Kenapa AI Gampang Menulis Test yang "Lolos" tapi Tidak Berguna
Model AI umumnya dilatih untuk menghasilkan kode yang valid secara sintaks dan, kalau diberi konteks fungsi, akan mencoba menebak perilaku yang diharapkan. Masalahnya, tanpa arahan yang jelas, AI cenderung mengambil jalan paling aman: menguji bahwa fungsi tidak melempar error, atau menguji nilai balik yang sama persis dengan implementasi yang sedang dibaca olehnya. Ini yang saya sebut test cermin — test yang pada dasarnya menyalin ulang logika implementasi, bukan menguji kontrak perilaku dari fungsi tersebut. Test seperti ini akan selalu hijau selama implementasinya tidak berubah, bahkan kalau implementasinya salah dari awal.
Contoh sederhana, kalau AI diminta menulis test untuk fungsi hitung diskon, ada kemungkinan dia menulis assertion yang cuma mengecek angka hasil perhitungan itu sendiri, tanpa menguji kasus batas seperti diskon 0%, diskon di atas 100%, atau input negatif. Coverage tool akan melaporkan baris itu "tercakup", padahal skenario yang paling rawan bug justru tidak pernah diuji.
Ciri Test yang Menguji Perilaku, Bukan Implementasi
Test yang berguna itu punya ciri yang bisa dicek relatif cepat saat review:
- Nama test menjelaskan perilaku yang diharapkan, bukan nama fungsi teknisnya. Misalnya
ia_menolak_transaksi_saat_saldo_tidak_cukupjauh lebih informatif daripadatest_prosesTransaksi. - Ada kasus batas dan kasus gagal, bukan cuma jalur bahagia (happy path).
- Assertion memeriksa hasil yang bermakna bagi bisnis — status, pesan error, perubahan data — bukan sekadar "fungsi tidak error".
- Kalau saya sengaja merusak logikanya sedikit, test itu seharusnya gagal. Kalau tidak gagal, test itu tidak menguji apa-apa.
Cara paling praktis untuk memverifikasi poin terakhir adalah teknik yang mirip dengan mutation testing: bayangkan atau coba langsung ubah satu baris logika inti (misalnya balik kondisi if, atau ganti operator perbandingan), lalu jalankan test-nya. Kalau semua test tetap hijau, berarti test itu belum benar-benar menjaga perilaku tersebut.
Cara Review Test Hasil AI dengan Cepat
Saya tidak membaca ulang setiap baris test hasil AI dengan teliti seperti membaca kode produksi. Yang saya lakukan lebih fokus:
- Baca nama-nama test dulu, tanpa lihat isinya. Kalau dari nama saja saya sudah tidak yakin skenario apa yang mau dijamin, itu tanda test perlu ditulis ulang.
- Cek apakah ada test untuk kasus gagal/kasus kosong/kasus batas, bukan cuma kasus normal.
- Minta AI sendiri menjelaskan, dalam satu kalimat, perilaku apa yang dijamin oleh tiap test — kalau jawabannya cuma mengulang nama fungsi, test itu kemungkinan test cermin.
- Untuk logika yang kritis (perhitungan biaya, validasi input medis, keputusan otorisasi), saya sengaja rusak implementasinya sebentar untuk memastikan test-nya benar-benar gagal.
Takeaway
AI adalah alat yang sangat membantu untuk mempercepat penulisan test, terutama untuk kasus-kasus rutin dan boilerplate yang membosankan ditulis manual. Tapi tanggung jawab untuk memastikan test itu benar-benar menjaga perilaku sistem, bukan cuma menaikkan angka coverage, tetap ada di tangan kita sebagai developer. Perlakukan test hasil AI seperti pull request dari rekan kerja: review dengan pertanyaan "kalau bug ini terjadi, apakah test ini akan menangkapnya?" — bukan sekadar "apakah test ini lolos?"