Bagaimana seharusnya kita bersikap defensif?

11

Kami telah menjalankan Pex pada beberapa kode, dan telah menunjukkan beberapa hal yang baik (hal-hal yang sangat buruk, tetapi menunjukkannya sebelum produksi!).

Namun, salah satu hal yang menyenangkan tentang Pex adalah tidak selalu berhenti mencari masalah.

Satu area yang kami temukan adalah ketika melewati sebuah string, kami tidak memeriksa string kosong.

Jadi kami berubah:

if (inputString == null)

untuk

if (string.IsNullOrEmpty(inputString)) // ***

Itu memperbaiki masalah awal. Tetapi kemudian, ketika kami menjalankan Pex lagi, diputuskan bahwa:

inputString = "\0";

menyebabkan masalah. Lalu

inputString = "\u0001";

Apa yang telah kami putuskan adalah bahwa default dapat digunakan jika kami bertemu // ***dan bahwa kami senang melihat pengecualian yang disebabkan oleh input ganjil lainnya (dan menanganinya).

Apa itu cukup?

Peter K.
sumber
Sudahkah Anda memeriksa untuk melihat apakah Anda dapat mematikan beberapa peringatan? Saya tahu JTest juga akan melakukan itu, tetapi itu juga merupakan pilihan untuk mematikan beberapa rekomendasinya. Butuh beberapa waktu dengan mengubah pengaturan untuk mendapatkan profil uji kode yang kami sukai.
FrustratedWithFormsDesigner
@ Frustasi: Ya, tentu saja ada perubahan pada profil yang dapat kita lakukan dan lakukan. Omong-omong, Pex adalah alat yang hebat. Hasil yang ditunjukkannya hanya memicu pertanyaan.
Peter K.
Saya tidak punya jawaban untuk Anda, tetapi saya ingin mengucapkan terima kasih atas tautan ke hal Pex ini; itu terlihat cukup rapi jika itu yang saya pikirkan dan akan secara otomatis (?) membuat unit test untuk kode yang ada Kode yang saya kerjakan sangat besar dan tidak memiliki tes dan kode yang sangat erat sehingga tidak mungkin untuk memperbaiki apa pun.
Wayne Molina
@WayneM: Ya, ini cukup bagus, meskipun saya perlu membaca beberapa contoh untuk memahami apa yang dilakukannya. Untuk kode lawas, ini hebat. Ini bahkan lebih baik untuk kode baru!
Peter K.

Jawaban:

9

Tiga pertanyaan akan membantu Anda menentukan seberapa defensif dalam pengkodean Anda.

Pertama - Apa konsekuensi dari input yang buruk? Jika itu adalah pesan kesalahan pada salah satu PC pengembang Anda, mungkin tidak terlalu penting untuk bersikap defensif. Bisakah itu mengakibatkan gangguan keuangan pada klien, gangguan informasi akuntansi IE? Apakah ini sistem waktu nyata di mana kehidupan berisiko? Dalam skenario hidup / mati, mungkin harus ada lebih banyak validasi dan kode penanganan kesalahan daripada kode fitur yang sebenarnya.

Kedua, berapa banyak orang yang akan menggunakan kembali fungsi atau kode ini? Hanya kamu? Departemen Anda? Perusahaan Anda? Pelanggan Anda? Semakin luas penggunaan kode semakin defensif.

Ketiga - apa sumber input yang saya validasi? Jika input dari pengguna atau dari situs web publik, saya akan sangat defensif. Jika input selalu berasal dari kode Anda, bersikaplah agak defensif, tetapi jangan menghabiskan waktu yang tidak semestinya untuk melakukan cek.

Akan selalu dimungkinkan untuk menambahkan lebih banyak pengecekan kesalahan dan validasi dalam suatu sistem. Intinya adalah apakah biaya penulisan dan pemeliharaan kode ini lebih besar daripada biaya masalah yang disebabkan oleh kesalahan dalam kode.

Bork Blatt
sumber
6

Pengguna jahat, dan apa pun yang mereka input harus diperiksa dengan sangat teliti.

Apa pun yang dihasilkan tanpa manfaat dari input pengguna, atau dari data pra-sanitasi, tidak perlu diperiksa pada tingkat yang sama. Masalahnya di sini adalah ketika Anda lupa dan menggunakan metode ini pada data yang buruk, karena Anda lupa bahwa kode tidak mengeras.

Satu hal yang harus selalu Anda periksa adalah segala sesuatu yang dapat menyebabkan overflow atau crash. Tidak masalah seberapa dalam metode itu terkubur, dan seberapa yakin Anda bahwa kondisi itu tidak akan pernah terjadi. Anda harus memprogram untuk itu, hanya untuk menenangkan Murphy.

Satanicpuppy
sumber
2

Saya akan menjadi defensif seperti yang Anda inginkan. Agak ambigu, saya kira begitu tapi saya akan coba jelaskan.

Ketika Anda benar metode, jika metode itu memiliki parameter input Anda harus membuat keputusan tentang apa yang Anda harapkan menjadi parameter. Dalam situasi dan tempat dalam suatu aplikasi, ini akan berbeda. Misalnya, jika metode atau bagian kode menerima data dari input pengguna maka Anda ingin mencakup semua basis kode dan menangani input apa pun yang sesuai apakah melalui pesan kesalahan atau cara yang bagus untuk menampilkan data yang tidak dapat diterima.

Jika metodenya adalah API terbuka, terbuka. Anda tidak dapat mengontrol apa yang masuk sehingga Anda harus berharap untuk mencoba dan mencakup semua aspek dan program yang sesuai.

Untuk metode yang dihasilkan dalam mesin inti proyek Anda, di sini Anda harus membuat keputusan. Apakah saya berasumsi bahwa data yang tiba telah disaring dan divalidasi sebelum tiba atau haruskah saya memasukkan cek yang diperlukan. Saya kira ini tergantung pada tingkat konseptual metode dan apakah ini merupakan tempat yang dapat diterima untuk memeriksa. Jadi hal yang mungkin saya pertimbangkan adalah:

1) Apakah ini satu-satunya tempat saya perlu melakukan pemeriksaan ini? Apakah variabel ini perlu diperiksa di banyak tempat yang berbeda untuk kondisi ini. Jika demikian dapat saya lakukan pemeriksaan sekali lebih tinggi dari rantai dan kemudian menerima validitas sesudahnya

2) Apakah komponen lain dari sistem diharapkan bekerja dengan metode dan antarmuka yang saya tulis. Jika demikian, Anda dapat mengontrol melalui pernyataan penegasan debug, pengecualian debugging, komentar metode dan arsitektur sistem umum hasil yang Anda butuhkan, atau akankah data tersebut perlu dicek.

3) Apa hasil dari kegagalan pada titik ini dalam kode. Apakah ini akan menyebabkan semuanya gagal? Apakah ada kesalahan yang ditangkap di tempat lain dan setidaknya kesalahan itu akan tertangkap.

4) Apakah masuk akal untuk memberi tanda centang di sini? Kadang-kadang memberi tanda centang pada kemungkinan data yang korup meskipun membantu menyelesaikan masalah pada saat itu dan tidak membuat kesalahan bisa membantu menutupinya. Pada titik mana Anda mungkin menghabiskan berjam-jam mengejar masalah yang berbeda hanya untuk menemukan masalah yang sebenarnya adalah karena pemeriksaan yang valid pada data di balik rantai peristiwa yang mengalir ke yang dilaporkan pengguna / pengembang.

Secara umum saya seorang programmer defensif namun saya juga percaya bahwa dengan pengujian menyeluruh TDD dan unit yang tepat Anda dapat memasukkan cek dalam kode di tingkat yang diperlukan dan yakinlah bahwa itu berfungsi sebagaimana mestinya begitu sampai ke bagian tingkat yang lebih rendah .

dreza
sumber
1

Saya telah menghabiskan berminggu-minggu sebelumnya pada bug yang bisa dideteksi dengan 5 menit kerja ekstra seperti ini di muka. Dalam pikiran saya pekerjaan di muka ini selalu sepadan. Anda akan memperbaiki bug pada akhirnya. Satu-satunya pertanyaan adalah berapa lama Anda.

Satu hal yang sering ditemukan oleh alat analisis ini adalah hal-hal yang tidak selalu berupa bug, tetapi kebiasaan pemrograman yang buruk yang membuat bug lebih mungkin terjadi. Salah satu kebiasaan umum tersebut adalah inisialisasi variabel. Terkadang string kosong adalah nilai yang valid untuk sebuah variabel. Dalam hal ini, Anda ingin mengonfigurasi alat Anda untuk tidak menganggap itu kesalahan dalam contoh khusus itu. Namun, seringkali string kosong bukan nilai yang valid untuk suatu variabel, tetapi orang tetap menyetelnya, karena kompiler mengeluh jika tidak ada sesuatu di sana, atau bahasa Anda secara otomatis menginisialisasi ke string kosong apakah itu valid atau tidak.

Ini membuat orang frustasi karena tampaknya seperti tangkapan 22 tanpa solusi yang valid, tetapi solusinya adalah dengan memperbaiki kode Anda sehingga tidak perlu menginisialisasi variabel sampai ada nilai yang valid untuk dimasukkan ke sana. Itu membutuhkan beberapa pemikiran ekstra di depan, tetapi membuat kode Anda jauh lebih kuat, dan sebenarnya lebih mudah untuk menulis dan memelihara dalam jangka panjang.

Karl Bielefeldt
sumber