Kenapa Code Coverage Tidak Boleh Menjadi Tujuan Utama Unit Test
Dalam praktik software engineering, code coverage sering dijadikan metrik utama untuk menilai kualitas unit test. Target seperti minimal 80% atau 90% coverage kerap dipakai sebagai standar kelulusan pull request, CI pipeline, bahkan KPI tim engineering.
Sekilas, pendekatan ini terlihat masuk akal. Semakin banyak kode yang diuji, seharusnya semakin kecil kemungkinan bug lolos ke production. Namun dalam praktiknya, menjadikan code coverage sebagai tujuan utama justru sering menyesatkan dan merusak esensi dari unit testing itu sendiri.
Artikel ini membahas secara mendalam kenapa code coverage tidak seharusnya menjadi tujuan, apa dampak negatifnya jika dijadikan target, dan bagaimana cara memposisikan code coverage secara lebih sehat dalam proses pengembangan software.
Apa Itu Code Coverage (dan Apa yang Tidak Diukurnya)
Secara sederhana, code coverage mengukur seberapa banyak baris, cabang, atau kondisi kode yang dieksekusi oleh test. Ia tidak mengukur:
- Apakah hasil yang diuji benar
- Apakah logika bisnis tervalidasi
- Apakah edge case penting tertangani
- Apakah test benar-benar akan menangkap bug
Artinya, sebuah test bisa mengeksekusi kode tanpa melakukan assertion yang berarti — dan tetap dihitung sebagai coverage.
Coverage hanya menjawab pertanyaan: “kode ini dijalankan?”, bukan “kode ini benar?”
Masalah Utama Ketika Code Coverage Dijadikan Tujuan
Fokus Bergeser dari Kualitas ke Angka
Ketika target coverage ditetapkan (misalnya minimal 80%), mindset tim sering berubah menjadi:
“Yang penting coverage naik.”
Akibatnya:
- Test ditulis hanya untuk melewati baris kode
- Assertion dibuat asal-asalan
- Skenario penting justru diabaikan karena sulit diuji
Unit test yang seharusnya memverifikasi perilaku berubah menjadi sekadar formalitas administratif.
Esensi Unit Test Terlupakan
Tujuan utama unit test adalah:
- Memastikan unit kode bekerja sesuai kontrak
- Menangkap bug sejak dini
- Memberi rasa aman saat refactor
- Menjadi dokumentasi perilaku sistem
Ketika coverage menjadi target utama, unit test kehilangan makna tersebut. Test tidak lagi ditulis untuk melindungi sistem, melainkan untuk melindungi angka.
Ini berbahaya, karena kita bisa merasa aman hanya karena coverage tinggi, padahal test tersebut tidak menguji hal-hal yang benar-benar penting.
Rasa Aman Palsu
Coverage tinggi sering memberikan ilusi bahwa sistem sudah “aman”. Padahal:
- Bug kritikal bisa lolos meski coverage 100%
- Edge case bisnis sering tidak tersentuh
- Test hanya memverifikasi jalur bahagia (happy path)
Ini adalah contoh klasik false confidence. Sistem terlihat sehat di laporan, tetapi rapuh di dunia nyata.
Test Menjadi Sulit Dirawat
Test yang ditulis hanya demi coverage biasanya:
- Tidak jelas apa tujuannya
- Sangat terikat dengan implementasi
- Mudah rusak saat refactor kecil
Akibatnya, tim mulai:
- Takut mengubah kode karena test mudah gagal
- Menghapus test lama karena “mengganggu”
- Menganggap unit test sebagai beban
Ironisnya, ini justru berlawanan dengan tujuan awal unit testing.
Membuang Waktu untuk Hal yang Tidak Bernilai
Tidak semua kode memiliki nilai bisnis yang sama.
Mengejar coverage sering membuat tim:
- Menulis test berlebihan untuk kode trivial
- Menghabiskan waktu pada bagian yang risikonya rendah
- Mengorbankan waktu untuk test yang sebenarnya lebih penting
Waktu engineer adalah sumber daya mahal. Menggunakannya untuk menaikkan angka tanpa nilai nyata adalah pemborosan.
Goodhart’s Law dalam Code Coverage
Ada prinsip terkenal:
When a measure becomes a target, it ceases to be a good measure.
Code coverage sangat cocok dengan prinsip ini.
Saat coverage dijadikan target:
- Angka kehilangan maknanya
- Perilaku tim berubah untuk memanipulasi metrik
- Metrik tidak lagi mencerminkan kualitas
Lalu, Bagaimana Posisi Code Coverage yang Sehat?
Code coverage sebaiknya dijadikan alat bantu, bukan tujuan.
Gunakan coverage untuk:
- Menemukan bagian kode yang sama sekali belum diuji
- Mengidentifikasi area berisiko tinggi tanpa test
- Membantu diskusi, bukan sebagai palu aturan
Yang seharusnya menjadi fokus utama:
- Apakah perilaku bisnis tervalidasi?
- Apakah test akan gagal jika terjadi bug nyata?
- Apakah test membantu refactor dengan percaya diri?
Jika jawabannya “ya”, maka coverage hanyalah efek samping yang baik — bukan target yang harus dikejar.
Kesimpulan
- Code coverage bukan indikator kualitas
- Menjadikannya tujuan utama merusak esensi unit testing
- Coverage tinggi bisa memberi rasa aman palsu
- Unit test harus fokus pada perilaku, risiko, dan nilai bisnis
- Coverage paling efektif digunakan sebagai guide, bukan goal
Unit test yang baik bukan diukur dari berapa persen kode yang dijalankan, tetapi dari seberapa besar kepercayaan yang ia berikan saat sistem berubah.
Jika tim berhenti mengejar angka dan mulai fokus pada makna test, kualitas software akan meningkat secara alami — dengan atau tanpa target coverage.