Bagaimana cara mengurangi jumlah bug saat coding?

30

Tidak ada yang sempurna, dan apa pun yang kita lakukan, kita akan menghasilkan kode yang memiliki bug di dalamnya dari waktu ke waktu. Apa beberapa metode / teknik untuk mengurangi jumlah bug yang Anda hasilkan, baik saat menulis perangkat lunak baru dan mengubah / memelihara kode yang ada?

GSto
sumber
Metode yang baik adalah melakukan desain awal lebih banyak (tidak terlalu banyak, tetapi cukup untuk membuat kode Anda lebih terstruktur dan lebih mudah dipahami).
Giorgio

Jawaban:

58

Hindari pengkodean yang mewah. Semakin rumit kode, semakin besar kemungkinan ada bug. Biasanya pada sistem modern, kode yang ditulis dengan jelas akan cepat dan cukup kecil.

Gunakan perpustakaan yang tersedia. Cara termudah untuk tidak memiliki bug menulis rutin utilitas adalah dengan tidak menulisnya.

Pelajari beberapa teknik formal untuk hal-hal yang lebih rumit. Jika ada kondisi rumit, kalahkan mereka dengan pena dan kertas. Idealnya, ketahui beberapa teknik pembuktian. Jika saya dapat membuktikan kode yang benar, itu hampir selalu baik kecuali untuk bug besar, bodoh, jelas yang mudah diperbaiki. Jelas, ini hanya berjalan sejauh ini, tetapi kadang-kadang Anda dapat secara formal alasan tentang hal-hal kecil tapi rumit.

Untuk kode yang ada, pelajari cara melakukan refactor: cara membuat perubahan kecil dalam kode, sering menggunakan alat otomatis, yang membuat kode lebih mudah dibaca tanpa mengubah perilaku.

Jangan melakukan sesuatu terlalu cepat. Mengambil sedikit waktu di depan untuk melakukan hal-hal yang benar, untuk memeriksa apa yang telah Anda lakukan, dan untuk memikirkan apa yang Anda lakukan dapat membayar banyak waktu nanti.

Setelah Anda menulis kode, gunakan apa yang Anda miliki untuk membuatnya menjadi baik. Tes unit sangat bagus. Anda dapat sering menulis tes sebelumnya, yang bisa menjadi umpan balik yang bagus (jika dilakukan secara konsisten, ini adalah pengembangan yang didorong oleh tes). Kompilasi dengan opsi peringatan, dan perhatikan peringatan itu.

Dapatkan orang lain untuk melihat kode. Ulasan kode formal bagus, tetapi mungkin tidak pada waktu yang tepat. Tarik permintaan, atau yang serupa jika SCM Anda tidak mendukungnya, memungkinkan untuk ulasan yang tidak sinkron. Pengecekan teman bisa menjadi tinjauan yang kurang formal. Pemrograman pasangan memastikan dua pasang mata melihat segalanya.

David Thornley
sumber
x2 - apa yang dikatakan Ryan.
JBRWilkinson
2
juga sebagian besar bahasa bisa lebih atau kurang pilih-pilih. Anda ingin pilih-pilih.
1
"Pelajari beberapa teknik formal untuk hal-hal yang lebih rumit." ... Misalnya?
Dan Rosenstark
1
@Yar: Saya mengharapkan sesuatu seperti sistem yang dijelaskan dalam buku ini: amazon.com/Verification-Sequential-Concurrent-Programs-Computer/… ; walaupun saya harus mengatakan bahwa buku tertentu sangat kering dan kusam, jadi mungkin ada yang lebih baik di luar sana (tapi itu satu-satunya yang saya baca).
Joeri Sebrechts
30

Unit Test memungkinkan Anda mengurangi jumlah bug yang muncul untuk kedua kalinya. Jika Anda menemukan bug dalam kode Anda, menulis unit test akan memastikan itu tidak muncul lagi nanti. (Plus, memikirkan semua kasus dan menulis ribuan unit test di depan terkadang sulit dilakukan)

Ryan Hayes
sumber
3
"Memikirkan semua kasing di muka" mengarah ke antarmuka yang bersih dan lengkap, yang hanya bisa menjadi hal yang baik. Tes unit hanya sulit untuk ditulis jika Anda memperbaikinya dengan kode yang tidak dirancang dengan pengujian dalam pikiran.
Mike Seymour
1
Jika Anda bisa, Anda harus melakukannya. Sayangnya, sebagian besar tempat saya telah melihat unit test sebagai sesuatu yang harganya lebih dari sekadar "memperbaiki bug dengan sangat cepat". Jadi, jika Anda bisa, maka Anda harus menulis tes di muka, tetapi jika itu tidak dilihat sebagai "hemat biaya" maka menulisnya bersama perbaikan bug membantu Anda membangunnya dari waktu ke waktu tanpa meletakkan terlalu banyak anggaran untuk hanya menulis tes unit .
Ryan Hayes
4
"Pengujian menunjukkan keberadaan, bukan tidak adanya bug." - E. Dijkstra. Karena itu, pengujian otomatis jelas merupakan cara yang sangat berguna untuk mempertahankan dan meningkatkan kualitas perangkat lunak.
limist
9

+1 pada kedua komentar unit test.

Selain itu, setel tingkat peringatan tertinggi yang ditawarkan kompiler Anda, dan pastikan peringatan diperlakukan sebagai kesalahan. Bug sering bersembunyi di kesalahan "keliru" itu.

Demikian pula, berinvestasi dalam alat analisis statis yang berjalan pada waktu kompilasi (saya melihat ini sebagai tingkat tambahan peringatan kompiler).

Alan
sumber
+1 untuk komentar analisis statis. Sangat berharga untuk mendapatkan semua info itu gratis :)
Morten Jensen
9

Selain apa yang telah disebutkan:

  • Jangan abaikan kode kesalahan - mis. Jangan berasumsi bahwa Anda mendapat hasil yang valid, bahwa file telah berhasil dibuat, dll ... Karena suatu hari, sesuatu akan terjadi.
  • Jangan berasumsi bahwa kode Anda tidak akan pernah memasuki kondisi tertentu dan karena itu "aman untuk mengabaikan kondisi itu".
  • Uji kode Anda, lalu uji oleh orang lain. Saya menemukan saya orang terburuk yang menguji kode saya sendiri.
  • Beristirahatlah, kemudian baca kembali kode Anda dan lihat apakah Anda "melewatkan yang sudah jelas". Sering terjadi pada saya.

Banyak hal lain yang saya lupa saat ini, tetapi yang lain pasti akan memikirkan mereka. :)

MetalMikester
sumber
7
Dan jika Anda begitu yakin bahwa kondisi X tidak akan pernah terjadi ... gunakan pernyataan untuk memastikan bahwa ketika kondisi X terjadi, Anda akan mengetahuinya (melalui pengecualian, atau pencatatan, atau apa pun).
Frank Shearar
@MetalMikester: Tes unit bagus. Tetapi dengan bahasa tingkat tinggi dan perpustakaan yang baik, sebagian besar hard bug memerlukan integrasi dan pengujian regresi untuk memakukan.
Vektor
9

Saya telah mengembangkan gaya pemrograman yang cukup fungsional, meskipun bahasa utama saya adalah C ++ dan Python. Saya menemukan bahwa jika saya meneruskan semua konteks ke fungsi (atau metode) yang fungsi itu perlu melakukan tugasnya, dan mengembalikan data bermakna yang saya cari, kode saya menjadi jauh lebih kuat.

Status tersirat adalah musuh dan dalam pengalaman saya adalah sumber bug nomor 1. Status ini bisa berupa variabel global atau variabel anggota, tetapi jika hasilnya bergantung pada sesuatu yang tidak diteruskan ke fungsi yang Anda minta masalah. Jelas itu tidak layak untuk menghilangkan negara, tetapi meminimalkan itu memiliki efek positif besar pada keandalan program.

Saya juga ingin memberi tahu rekan kerja saya bahwa setiap cabang (jika, untuk, sementara,? :) kemungkinan adalah bug. Saya tidak bisa mengatakan apa manifestasi dari bug tersebut, tetapi semakin sedikit perilaku kondisional yang dimiliki kode Anda, semakin besar kemungkinan bug itu bebas hanya karena fakta bahwa cakupan kode selama eksekusi akan lebih konsisten.

Go figure, semua hal ini juga memiliki efek positif pada kinerja juga. Menang!

dash-tom-bang
sumber
Dalam pengalaman saya, dapat dengan cepat menjadi membosankan untuk melewati semua keadaan untuk setiap panggilan, jika metodenya sekecil yang seharusnya. Masalah ini dapat diselesaikan dengan menggunakan banyak kelas kecil yang tidak dapat diubah dengan objek pendek seumur hidup. Dengan begitu, Anda dapat menyimpan status sementara sebagai bidang dan membuang objek saat Anda tidak lagi membutuhkannya. :-)
Jørgen Fogh
Pertimbangan lain untuk kasus itu menjadi membosankan adalah bahwa mungkin Anda mencoba untuk melewati terlalu banyak keadaan. :)
dash-tom-bang
Dalam banyak kasus itu benar tetapi seringkali tidak. Dalam beberapa domain Anda memerlukan akses ke banyak negara, bahkan jika Anda tidak memiliki banyak negara yang bisa berubah . Saat ini saya sedang mengerjakan generator kode di mana saya perlu akses ke beberapa tabel simbol. Saya tidak ingin membagikannya ke setiap metode.
Jørgen Fogh
8
  • Tulis lebih sedikit kode yang menghasilkan lebih banyak.
  • Pikirkan tentang implikasi tingkat rendah dan konsekuensi tingkat tinggi
  • Renungkan abstraksi yang Anda buat dalam kode Anda.
  • Tuliskan hanya kompleksitas esensial jika memungkinkan.
Paul Nathan
sumber
Saya akan menulis posting besar yang meringkas sebagai "menulis lebih sedikit yang lebih banyak" (IOW tahu dan menggunakan alat yang tersedia untuk Anda). Saya hanya akan memberi ini +1.
Kaz Dragon
1
Tapi hati-hati jangan sampai mendapatkan kode mewah ketika mencoba mencapai kode yang lebih sedikit.
gablin
1
@ Gablin: mewah ada di mata yang melihatnya dalam banyak hal. Saya dapat menulis dan membaca kode hari ini bahwa saya akan terpana 4 tahun yang lalu. Haskell hari ini sangat mewah bagiku. :)
Paul Nathan
8

Jawaban yang sedikit kurang teknis: jangan memprogram ketika Anda lelah (9 jam / hari sudah cukup), mabuk atau 'dipanggang'. Ketika saya lelah saya tidak memiliki kesabaran untuk menulis kode yang bersih.

Alexandru
sumber
2
Biasanya dibutuhkan sebagian besar programmer beberapa tahun untuk menyadari hal ini. Ini poin penting.
Jeff Davis
7

Tulis tes unit dan tes integrasi .

ysolik
sumber
5

Beberapa jawaban bagus di sini mengenai pengujian unit dan alat. Satu-satunya hal yang dapat saya tambahkan kepada mereka adalah ini:

Libatkan penguji Anda sedini mungkin

Jika Anda memiliki tim uji coba, jangan terjebak dalam memperlakukan mereka sebagai penjaga gerbang untuk kualitas kode Anda dan menangkap cacat Anda untuk Anda. Alih-alih, bekerjalah dengan mereka dan libatkan mereka sedini mungkin (pada proyek yang gesit ini akan dimulai dari awal proyek, tetapi kita selalu dapat menemukan cara untuk melibatkan mereka lebih awal jika kita benar-benar mencoba).

  • Cari tahu apa rencana pengujian mereka. Tinjau kasus pengujian mereka dengan mereka - apakah Anda menutupi semuanya dengan kode Anda?
  • Mintalah mereka untuk memahami persyaratan. Apakah sama dengan milikmu?
  • Berikan mereka bangunan kerja awal untuk melakukan pengujian eksplorasi - Anda akan kagum dengan perbaikan yang mereka sarankan.

Memiliki hubungan kerja yang baik dengan penguji Anda berarti Anda dapat menangkap asumsi dan cacat yang buruk sejak awal, sebelum mereka dapat melakukan kerusakan. Ini juga berarti bahwa penguji merasa diberdayakan untuk membantu dengan desain produk dan menangkap masalah kegunaan ketika ada waktu untuk memperbaikinya.

Paddyslacker
sumber
4

Alat Analisis Statis

Plugin dan aplikasi seperti FindBugs merayapi kode Anda dan menemukan tempat di mana ada bug potensial . Tempat di mana variabel tidak diinisialisasi dan digunakan atau hanya hal-hal gila yang 9 kali dari 10, membuatnya lebih mudah untuk bug muncul. Alat seperti ini membantu saya mencegah tulang kepala saya bergerak di jalan meskipun itu belum bug.

PS: Ingatlah untuk selalu meneliti mengapa alat memberi tahu Anda ada sesuatu yang buruk. Tidak ada salahnya belajar (dan tidak semuanya benar dalam semua situasi).

Ryan Hayes
sumber
3

Inspeksi kode atau bentuk-bentuk peer review lainnya seperti pemrograman pasangan.

Ulasan kode terstruktur seperti inspeksi Fagan setidaknya dapat seefektif dan seefisien pengujian unit dan bahkan terbukti lebih baik daripada pengujian unit dalam beberapa kasus. Inspeksi juga dapat digunakan lebih awal dalam siklus hidup perangkat lunak dan dengan artefak selain kode.

Peer Reviews in Software oleh Karl Wiegers adalah buku yang bagus tentang hal ini.

Michael
sumber
2

Selain semua saran lainnya di sini, nyalakan semua peringatan yang mungkin sampai tingkat sensitivitas tertinggi, dan perlakukan itu sebagai kesalahan. Gunakan juga alat bantu linting yang dimiliki bahasa.

Anda akan kagum pada berapa banyak kesalahan sederhana dapat ditangkap oleh peringatan dan berapa banyak dari hal-hal sederhana yang diterjemahkan menjadi bug nyata dalam kode Anda.

greyfade
sumber
2

Banyak jawaban bagus di sini, tetapi beberapa hal yang ingin saya tambahkan. Pastikan Anda benar-benar memahami persyaratannya. Saya telah melihat banyak bug ketika pengguna berpikir persyaratan berarti X dan programmer berpikir itu berarti Y. Dorong kembali untuk klarifikasi tentang persyaratan yang buruk atau ambigu. Saya tahu kita semua suka melompat dan kode tetapi semakin banyak waktu yang dihabiskan di depan memastikan pemahaman, semakin sedikit pengerjaan ulang dan perbaikan bug akan ada.

Mengenal bisnis yang Anda dukung, Anda akan sering melihat hal-hal dalam persyaratan yang hilang atau butuh penjelasan lebih lanjut. Ketahuilah bahwa jika Anda melakukan tugas Y sebagaimana dinyatakan, itu akan merusak fitur Z.

Pahami struktur basis data Anda. Banyak banyak bug sebagai hasil dari kueri yang secara sintaksis benar, tetapi mengembalikan hasil yang salah. Pelajari cara mengenali kapan hasil Anda terlihat lucu. Jika saya menulis kueri pelaporan yang kompleks, saya selalu meminta spesialis teknis untuk meninjau hasil sebelum saya menandainya sebagai siap untuk digunakan, mereka pasti akan melihat sesuatu dalam data yang saya lewatkan. Kemudian buat catatan untuk diri sendiri apa yang mereka tangkap yang tidak Anda ketahui dan ingat bahwa lain kali Anda melakukan sesuatu yang serupa.

HLGEM
sumber
1

Saya pikir teknik yang paling penting adalah meluangkan waktu Anda . Jika Anda merasa perlu dua hari untuk membuat kode modul baru, tetapi bos Anda memaksa Anda untuk membuat kode hanya dalam satu hari ... kode Anda kemungkinan besar akan bermasalah.

Salah satu buku yang saya baca beberapa waktu lalu, mengatakan bahwa Anda tidak boleh hidup dengan jendela pecah , karena orang tidak akan peduli jika orang lain rusak ... Pengodeannya sama, semua orang akan peduli menjadi yang pertama dalam melakukan sesuatu yang buruk tapi cepat , tetapi tidak ada yang peduli dengan satu kode neraka , dengan banyak bug, dan desain dan gaya yang sangat buruk.

greuze
sumber
1

Saya mengikuti praktek Test-Code-Test alih-alih Code-test-code-test. Ini membantu saya untuk memikirkan use case dan membingkai logika dengan tepat

viv
sumber
1

Gunakan alat inspeksi kode seperti ReSharper atau IDE seperti IntelliJ IDEA yang memperingatkan tentang banyak bug salin dan tempel dan lainnya dengan misalnya menunjukkan variabel yang "ditulis, tetapi tidak pernah dibaca". Telah menghemat banyak waktu.

DonJoe
sumber
1

Yang mengejutkan, tiga poin penting berikut ini belum disebutkan:

  • Gunakan pernyataan secara bebas. Pertanyaan yang harus selalu Anda tanyakan pada diri sendiri bukanlah "haruskah saya menegaskan hal ini?" tetapi "apakah ada sesuatu yang saya lupa nyatakan?"

  • Pilihlah untuk kekekalan. (Gunakan final / hanya baca secara bebas.) Semakin sedikit keadaan Anda yang berubah, semakin sedikit hal yang bisa salah.

  • Jangan optimalkan secara prematur. Banyak programer dilacak dengan masalah kinerja, menyebabkan mereka tidak perlu membelit kode mereka dan membombardir desain mereka tanpa tahu sebelumnya apakah kinerja akan menjadi masalah. Pertama, buat produk perangkat lunak Anda dengan cara akademis, dengan mengabaikan kinerja; kemudian, lihat apakah kinerjanya buruk; (Mungkin tidak akan.) Jika ada masalah kinerja, cari satu atau dua tempat di mana Anda dapat memberikan optimasi algoritme yang bagus dan formal yang akan membuat produk Anda memenuhi persyaratan kinerjanya alih-alih mengubah dan meretas seluruh basis kode Anda untuk memeras siklus jam di sana-sini.

Mike Nakis
sumber