Aplikasi terbuka tanpa masalah. Semua tombol berfungsi. Tidak ada pesan kesalahan. Tetapi, siapa yang menjamin bahwa hasil perhitungannya sudah benar?

Dalam pemrograman, keberhasilan menjalankan sebuah program sering dianggap sebagai tanda bahwa pekerjaan telah selesai. Kode berhasil dieksekusi, aplikasi tidak berhenti mendadak, dan hasil muncul sesuai format yang diharapkan. Bagi pengguna, kondisi tersebut memberikan kesan bahwa sistem bekerja sebagaimana mestinya.

Padahal, program yang berjalan lancar belum tentu menghasilkan jawaban yang tepat. Komputer dapat menjalankan instruksi dengan benar, sementara instruksi yang diberikan ternyata mengandung kesalahan logika. Akibatnya, sebuah aplikasi bisa menghasilkan informasi keliru tanpa menunjukkan tanda-tanda kerusakan.

Persoalan ini menjadi semakin penting ketika perangkat lunak digunakan untuk menghitung transaksi, mengolah data kesehatan, mengelola persediaan, atau mendukung pengambilan keputusan. Kesalahan yang membuat aplikasi berhenti biasanya segera terlihat. Sebaliknya, kesalahan yang menghasilkan jawaban masuk akal justru berpotensi bertahan lebih lama karena tidak langsung menimbulkan kecurigaan.

Baca Juga: Programnya Berjalan dengan Baik, Kenapa Developer Masih Mau Mengubah Kodenya?

Ketika Komputer Menjalankan Instruksi yang Keliru dengan Sempurna

Bayangkan sebuah toko memiliki aplikasi untuk menghitung harga setelah diskon. Sebuah barang dijual seharga Rp200.000 dengan potongan harga 20 persen, kemudian dikenai pajak 11 persen. Apabila pajak dihitung dari harga setelah diskon, pelanggan seharusnya membayar Rp177.600.

Akan tetapi, pengembang aplikasi mungkin keliru menuliskan urutan perhitungannya. Program menghitung pajak dari harga awal, lalu mengurangi diskon sehingga menghasilkan total Rp182.000. Tidak ada kesalahan sintaks, aplikasi tetap berjalan, dan angka yang muncul terlihat wajar.

Contoh tersebut memperlihatkan perbedaan antara kesalahan dalam penulisan kode dan kesalahan dalam logika program. Kesalahan sintaks umumnya dapat dikenali ketika kode diperiksa atau dijalankan karena melanggar aturan bahasa pemrograman. Sementara itu, logical error dapat tersembunyi di balik kode yang secara teknis sah dan dapat dieksekusi.

Dalam ilmu komputer, persoalan ini berkaitan dengan perbedaan antara keberhasilan eksekusi dan kebenaran perilaku program. Sebuah program bisa menjalankan setiap instruksi sesuai aturan bahasa pemrogramannya tanpa memenuhi tujuan yang sebenarnya diinginkan pengguna. Komputer tidak secara otomatis mengetahui apakah rumus, asumsi, atau aturan bisnis yang diberikan pengembang sudah tepat.

Kesalahan juga dapat muncul dari data yang digunakan. Program penghitung rata-rata, misalnya, mungkin menghasilkan angka yang benar secara matematis, tetapi datanya mengandung nilai ganda atau catatan yang seharusnya tidak disertakan. Hasil perhitungan menjadi tidak representatif meskipun operasi aritmatikanya berjalan sempurna.

Persoalan serupa dapat terjadi ketika pengembang tidak mempertimbangkan kondisi tertentu yang jarang muncul. Dalam pemrograman, kondisi semacam ini sering disebut edge case. Contohnya adalah pembagian dengan nilai nol, tanggal 29 Februari, transaksi dengan nilai negatif, atau jumlah pengguna yang melampaui batas yang diperkirakan.

Sebuah aplikasi mungkin berhasil melewati ratusan pengujian menggunakan data biasa, tetapi memberikan hasil keliru ketika menghadapi kondisi tersebut. Kesalahan seperti ini tidak selalu membuat sistem berhenti bekerja. Ada kalanya aplikasi tetap menghasilkan keluaran sehingga pengguna tidak menyadari bahwa sesuatu telah berjalan di luar asumsi awal.

Keadaan tersebut dapat menjadi bentuk silent failure, yakni kegagalan yang tidak disertai tanda kesalahan yang jelas bagi pengguna atau sistem pemantauan. Program terlihat aktif dan terus memproses data, tetapi hasilnya tidak sesuai dengan yang diharapkan. Istilah ini menggambarkan gejala kegagalan yang tersembunyi, bukan satu jenis kesalahan pemrograman yang memiliki penyebab tunggal.

Baca Juga: Kenapa Satu Perubahan Kecil pada Program Bisa Merusak Bagian yang Tampaknya Tidak Berhubungan?

Mengapa Pengujian Tidak Bisa Menjamin Program Bebas Kesalahan?

Ilmuwan komputer Edsger W. Dijkstra pernah mengemukakan gagasan penting mengenai keterbatasan pengujian perangkat lunak. Dalam ceramahnya yang diterbitkan sebagai Notes on Structured Programming pada 1970, ia menyatakan bahwa pengujian dapat menunjukkan keberadaan kesalahan, tetapi tidak dapat membuktikan bahwa kesalahan sama sekali tidak ada. Pemikiran tersebut menjadi salah satu pengingat penting dalam praktik rekayasa perangkat lunak.

Artinya, keberhasilan sebuah program melewati sejumlah pengujian belum cukup untuk memastikan bahwa program tersebut akan selalu menghasilkan jawaban benar. Pengujian hanya memberikan bukti mengenai perilaku sistem pada kondisi yang benar-benar diperiksa. Kondisi lain yang belum diuji masih mungkin memperlihatkan kesalahan.

Karena itu, pengembang perangkat lunak menggunakan berbagai pendekatan untuk meningkatkan keandalan program. Salah satunya adalah unit testing, yaitu pengujian terhadap bagian-bagian kecil kode secara terpisah. Pengujian ini membantu memastikan bahwa fungsi tertentu menghasilkan keluaran yang sesuai untuk masukan yang telah ditentukan.

Dalam contoh aplikasi diskon, pengembang dapat membuat pengujian yang memeriksa hasil perhitungan untuk berbagai harga, persentase potongan, dan aturan pajak. Hasil yang diberikan program kemudian dibandingkan dengan nilai yang sebelumnya ditentukan sebagai jawaban benar. Apabila keduanya berbeda, pengujian akan menunjukkan bahwa terdapat perilaku yang perlu diperiksa.

Meski demikian, pengujian juga bergantung pada ketepatan jawaban acuan yang digunakan. Apabila pengembang keliru memahami aturan pajak sejak awal, pengujian yang dibuat berdasarkan pemahaman tersebut mungkin tetap dinyatakan berhasil. Program dan pengujiannya dapat sama-sama konsisten, tetapi keduanya mengacu pada asumsi yang salah.

Di sinilah pentingnya validation, yakni memastikan bahwa perangkat lunak benar-benar memenuhi kebutuhan dan tujuan pengguna. Pendekatan ini berbeda dari sekadar memeriksa apakah kode telah dibuat sesuai spesifikasi teknis. Sebuah sistem dapat memenuhi seluruh persyaratan tertulis, tetapi tetap gagal menyelesaikan persoalan apabila persyaratannya sendiri tidak tepat.

Dalam praktik pengembangan, pengujian juga dapat diperluas melalui pemeriksaan antarkomponen, peninjauan kode, pengujian kondisi ekstrem, dan evaluasi bersama pengguna. Setiap pendekatan membantu menemukan kelompok masalah yang berbeda. Tidak ada satu metode yang secara otomatis mampu menjamin seluruh kemungkinan kesalahan telah ditemukan.

Perkembangan kecerdasan buatan menambahkan tantangan baru dalam proses tersebut. AI kini dapat membantu menulis kode, menjelaskan fungsi, dan menyarankan pengujian dengan lebih cepat. Akan tetapi, kode yang dihasilkan AI tetap perlu diperiksa karena kelancaran penulisannya tidak menjamin bahwa logika dan asumsi yang digunakan sudah benar.

Pengembang juga perlu berhati-hati ketika meminta AI membuat kode sekaligus pengujiannya. Apabila keduanya disusun berdasarkan penafsiran kebutuhan yang sama-sama keliru, hasil pengujian dapat memberikan rasa aman yang menyesatkan. Pemeriksaan independen terhadap kebutuhan, contoh kasus, dan hasil yang diharapkan tetap diperlukan.

Persoalan ini mengingatkan bahwa kualitas perangkat lunak tidak dapat dinilai hanya dari tampilannya yang lancar atau kecepatannya menghasilkan jawaban. Program yang baik perlu memiliki logika yang sesuai, data yang dapat dipercaya, serta mekanisme pengujian dan evaluasi yang memadai. Bahkan setelah digunakan, sistem masih memerlukan pemantauan karena kondisi nyata dapat berbeda dari lingkungan pengembangan.

Keberhasilan menjalankan kode merupakan pencapaian teknis, tetapi bukan akhir dari proses memastikan kebenaran program. Kesalahan bisa bersembunyi dalam rumus, asumsi, data, maupun situasi yang belum pernah diuji. Karena itu, pengembang perlu terus mempertanyakan bukan hanya apakah program dapat berjalan, melainkan apakah hasilnya memang menjawab persoalan yang seharusnya diselesaikan.

Komputer dapat menjalankan instruksi dengan sangat konsisten, termasuk ketika instruksi tersebut keliru. Justru karena itulah kemampuan menemukan dan mempertanyakan kesalahan menjadi bagian penting dari pemrograman. Sebuah program yang tidak menampilkan pesan kesalahan mungkin telah berhasil dijalankan, tetapi kebenaran jawabannya masih harus dibuktikan. [][Rudi Tenggarawan/KK]

Penulisan artikel ini dibantu AI dan telah melewati proses kurasi Redaksi.