Saya penggemar menulis assert
cek dalam kode C ++ sebagai cara untuk menangkap kasus selama pengembangan yang tidak mungkin terjadi tetapi bisa terjadi karena bug logika dalam program saya. Ini adalah praktik yang baik secara umum.
Namun, saya perhatikan bahwa beberapa fungsi yang saya tulis (yang merupakan bagian dari kelas yang kompleks) memiliki 5+ penegasan yang terasa seperti berpotensi menjadi praktik pemrograman yang buruk, dalam hal keterbacaan dan pemeliharaan. Saya pikir itu masih bagus, karena masing-masing mengharuskan saya untuk berpikir tentang pra-dan pasca-kondisi fungsi dan mereka benar-benar membantu menangkap bug. Namun, saya hanya ingin meletakkan ini di luar sana untuk bertanya apakah ada paradigma yang lebih baik untuk menangkap kesalahan logika dalam kasus-kasus ketika sejumlah besar pemeriksaan diperlukan.
Komentar Emacs : Karena Emacs adalah IDE pilihan saya, saya memilikinya sedikit mengeluarkan pernyataan tegas yang membantu mengurangi perasaan kekacauan yang mereka dapat berikan. Inilah yang saya tambahkan ke file .emacs saya:
; gray out the "assert(...)" wrapper
(add-hook 'c-mode-common-hook
(lambda () (font-lock-add-keywords nil
'(("\\<\\(assert\(.*\);\\)" 1 '(:foreground "#444444") t)))))
; gray out the stuff inside parenthesis with a slightly lighter color
(add-hook 'c-mode-common-hook
(lambda () (font-lock-add-keywords nil
'(("\\<assert\\(\(.*\);\\)" 1 '(:foreground "#666666") t)))))
sumber
Jawaban:
Saya telah melihat ratusan bug yang akan dipecahkan lebih cepat jika seseorang telah menulis lebih banyak penegasan, dan tidak satu pun yang akan dipecahkan lebih cepat dengan menulis lebih sedikit .
Keterbacaan bisa menjadi masalah, mungkin - meskipun pengalaman saya bahwa orang yang menulis pernyataan yang baik juga menulis kode yang dapat dibaca. Dan itu tidak pernah mengganggu saya untuk melihat awal dari suatu fungsi dimulai dengan blok menegaskan untuk memverifikasi bahwa argumen itu bukan sampah - cukup masukkan baris kosong setelahnya.
Juga dalam pengalaman saya, rawatan selalu ditingkatkan dengan menegaskan, seperti halnya dengan unit test. Asserts memberikan kewarasan memeriksa bahwa kode sedang digunakan seperti yang dimaksudkan untuk digunakan.
sumber
Ya tentu saja. [Bayangkan contoh yang menjengkelkan di sini.] Namun, menerapkan pedoman yang dirinci di bawah ini, Anda seharusnya tidak kesulitan mendorong batas itu dalam praktik. Saya penggemar berat pernyataan juga, dan saya menggunakannya sesuai dengan prinsip-prinsip ini. Banyak dari saran ini tidak khusus untuk pernyataan tetapi hanya praktik rekayasa umum yang baik yang diterapkan padanya.
Jaga agar run-time dan jejak biner tetap diingat
Penegasan itu bagus, tetapi jika mereka membuat program Anda terlalu lambat, itu akan sangat mengganggu atau Anda akan mematikannya cepat atau lambat.
Saya suka mengukur biaya pernyataan relatif terhadap biaya fungsi yang terkandung di dalamnya. Perhatikan dua contoh berikut.
Fungsi itu sendiri adalah operasi O (1) tetapi pernyataan akun untuk O ( n ) overhead. Saya tidak berpikir Anda ingin cek seperti itu aktif kecuali dalam keadaan yang sangat khusus.
Berikut adalah fungsi lain dengan pernyataan serupa.
Fungsi itu sendiri adalah operasi O ( n ) sehingga sangat menyakitkan untuk menambahkan overhead O ( n ) tambahan untuk pernyataan tersebut. Memperlambat fungsi dengan faktor konstan kecil (dalam hal ini, mungkin kurang dari 3) adalah sesuatu yang biasanya dapat kita beli di build debug tetapi mungkin tidak dalam build rilis.
Sekarang perhatikan contoh ini.
Sementara banyak orang mungkin akan jauh lebih nyaman dengan pernyataan O (1) ini daripada dengan dua pernyataan O ( n ) dalam contoh sebelumnya, mereka secara moral setara dalam pandangan saya. Masing-masing menambahkan overhead pada urutan kompleksitas fungsi itu sendiri.
Akhirnya, ada pernyataan "benar-benar murah" yang didominasi oleh kompleksitas fungsi yang dikandungnya.
Di sini, kami memiliki dua pernyataan O (1) dalam fungsi O ( n ). Mungkin tidak akan menjadi masalah untuk mempertahankan overhead ini meskipun dalam rilis build.
Namun perlu diingat bahwa kompleksitas asimptotik tidak selalu memberikan perkiraan yang memadai karena dalam praktiknya, kita selalu berhadapan dengan ukuran input yang dibatasi oleh beberapa faktor konstan dan konstan yang disembunyikan oleh “Big- O ” mungkin tidak akan diabaikan.
Jadi sekarang kami telah mengidentifikasi skenario yang berbeda, apa yang bisa kami lakukan? Pendekatan (mungkin terlalu) mudah adalah mengikuti aturan seperti "Jangan gunakan pernyataan yang mendominasi fungsi yang ada di dalamnya." Sementara itu mungkin bekerja untuk beberapa proyek, yang lain mungkin membutuhkan pendekatan yang lebih berbeda. Ini bisa dilakukan dengan menggunakan makro pernyataan yang berbeda untuk kasus yang berbeda.
Anda sekarang dapat menggunakan tiga makro
MY_ASSERT_LOW
,MY_ASSERT_MEDIUM
danMY_ASSERT_HIGH
bukannya makro "satu ukuran cocok untuk semua" perpustakaan standarassert
untuk pernyataan yang didominasi oleh, tidak mendominasi atau mendominasi dan mendominasi kompleksitas fungsi masing-masing yang berisi. Saat Anda membangun perangkat lunak, Anda dapat menetapkan simbol pra-prosesorMY_ASSERT_COST_LIMIT
untuk memilih jenis pernyataan apa yang harus dibuat menjadi executable. KonstantaMY_ASSERT_COST_NONE
danMY_ASSERT_COST_ALL
tidak sesuai dengan makroMY_ASSERT_COST_LIMIT
pernyataan apa pun dan dimaksudkan untuk digunakan sebagai nilai untuk mematikan semua asersi atau masing-masing.Kami mengandalkan asumsi di sini bahwa kompiler yang baik tidak akan menghasilkan kode apa pun untuk
dan mentransformasikannya
ke
yang saya percaya adalah asumsi yang aman saat ini.
Jika Anda hendak men-tweak kode di atas, pertimbangkan penjelasan compiler-spesifik seperti
__attribute__ ((cold))
padamy::assertion_failed
atau__builtin_expect(…, false)
di!(CONDITION)
untuk mengurangi overhead dari pernyataan berlalu. Dalam rilis rilis, Anda juga dapat mempertimbangkan mengganti panggilan fungsimy::assertion_failed
dengan sesuatu seperti__builtin_trap
mengurangi jejak kaki karena ketidaknyamanan kehilangan pesan diagnostik.Optimalisasi semacam ini benar-benar hanya relevan dalam pernyataan yang sangat murah (seperti membandingkan dua bilangan bulat yang sudah diberikan sebagai argumen) dalam fungsi yang itu sendiri sangat kompak, tidak mempertimbangkan ukuran tambahan biner yang diakumulasikan dengan memasukkan semua string pesan.
Bandingkan bagaimana kode ini
dikompilasi ke dalam rakitan berikut
sedangkan kode berikut
memberikan majelis ini
yang saya merasa jauh lebih nyaman dengan. (Contoh diuji dengan GCC 5.3.0 menggunakan
-std=c++14
,-O3
dan-march=native
ditandai pada 4.3.3-2-ARCH x86_64 GNU / Linux. Tidak ditampilkan dalam cuplikan di atas adalah deklarasitest::positive_difference_1st
dantest::positive_difference_2nd
yang saya tambahkan__attribute__ ((hot))
ke.my::assertion_failed
Dideklarasikan dengan__attribute__ ((cold))
.)Menegaskan prasyarat dalam fungsi yang bergantung padanya
Misalkan Anda memiliki fungsi berikut dengan kontrak yang ditentukan.
Alih-alih menulis
di setiap situs panggilan, masukkan logika itu sekali ke dalam definisi
count_letters
dan menyebutnya tanpa basa-basi lagi.
Ini memiliki keuntungan sebagai berikut.
assert
pernyataan dalam kode Anda.Kerugian yang jelas adalah bahwa Anda tidak akan mendapatkan lokasi sumber situs panggilan ke dalam pesan diagnostik. Saya percaya bahwa ini adalah masalah kecil. Seorang debugger yang baik harus bisa membiarkan Anda melacak asal pelanggaran kontrak dengan mudah.
Pemikiran yang sama berlaku untuk fungsi "khusus" seperti operator kelebihan beban. Ketika saya menulis iterator, saya biasanya - jika sifat iterator memungkinkannya - beri mereka fungsi anggota
yang memungkinkan untuk bertanya apakah aman untuk dereferensi iterator. (Tentu saja, dalam praktiknya, hampir selalu hanya mungkin untuk menjamin bahwa itu tidak akan aman untuk mengulangi iterator. Tapi saya percaya Anda masih dapat menangkap banyak bug dengan fungsi seperti itu.) Daripada membuang sampah sembarangan semua kode saya yang menggunakan iterator dengan
assert(iter.good())
pernyataan, saya lebih suka menempatkan satuassert(this->good())
sebagai baris pertamaoperator*
dalam implementasi iterator.Jika Anda menggunakan pustaka standar, alih-alih menegaskan secara manual tentang prasyaratnya dalam kode sumber Anda, nyalakan pemeriksaan mereka dalam pembuatan debug. Mereka bahkan dapat melakukan pemeriksaan yang lebih canggih seperti menguji apakah wadah yang disebut iterator masih ada. (Lihat dokumentasi untuk libstdc ++ dan libc ++ (sedang berlangsung) untuk informasi lebih lanjut.)
Faktor kondisi umum keluar
Misalkan Anda sedang menulis paket aljabar linier. Banyak fungsi akan memiliki prasyarat yang rumit dan melanggarnya akan sering menyebabkan hasil yang salah yang tidak segera dikenali. Akan sangat baik jika fungsi-fungsi ini menegaskan prasyarat mereka. Jika Anda mendefinisikan sekelompok predikat yang memberi tahu Anda properti tertentu tentang struktur, pernyataan itu menjadi jauh lebih mudah dibaca.
Ini juga akan memberikan pesan kesalahan yang lebih bermanfaat.
membantu lebih banyak daripada, katakanlah
di mana Anda pertama kali harus melihat kode sumber dalam konteks untuk mencari tahu apa yang sebenarnya diuji.
Jika Anda memiliki
class
invarian non-sepele, mungkin ide yang baik untuk menyatakannya dari waktu ke waktu ketika Anda telah mengacaukan keadaan internal dan ingin memastikan bahwa Anda meninggalkan objek dalam keadaan valid saat pengembalian.Untuk tujuan ini, saya merasa berguna untuk mendefinisikan
private
fungsi anggota yang saya panggil secara konvensionalclass_invaraiants_hold_
. Misalkan Anda menerapkan kembalistd::vector
(Karena kita semua tahu itu tidak cukup baik.), Mungkin memiliki fungsi seperti ini.Perhatikan beberapa hal tentang ini.
const
dannoexcept
, sesuai dengan pedoman bahwa pernyataan tidak akan memiliki efek samping. Jika itu masuk akal, nyatakan jugaconstexpr
.assert(this->class_invariants_hold_())
. Dengan cara ini, jika pernyataan dikompilasi keluar, kita dapat yakin bahwa tidak ada overhead run-time yang dikeluarkan.if
pernyataan dengan awalreturn
s daripada ekspresi besar. Ini membuatnya mudah untuk melangkah melalui fungsi dalam debugger dan mencari tahu bagian invarian mana yang rusak jika pernyataan itu menyala.Jangan menegaskan hal-hal konyol
Beberapa hal tidak masuk akal untuk ditegaskan.
Pernyataan ini tidak membuat kode sedikit lebih mudah dibaca atau lebih mudah dipikirkan. Setiap programmer C ++ harus cukup percaya diri bagaimana cara
std::vector
kerjanya untuk memastikan bahwa kode di atas benar hanya dengan melihatnya. Saya tidak mengatakan bahwa Anda tidak boleh menegaskan ukuran wadahnya. Jika Anda telah menambahkan atau menghapus elemen menggunakan beberapa aliran kontrol non-sepele, pernyataan seperti itu bisa berguna. Tetapi jika itu hanya mengulangi apa yang ditulis dalam kode non-tegas di atas, tidak ada nilai yang didapat.Juga jangan nyatakan bahwa fungsi perpustakaan bekerja dengan benar.
Jika Anda mempercayai perpustakaan itu sedikit, lebih baik pertimbangkan untuk menggunakan perpustakaan lain.
Di sisi lain, jika dokumentasi perpustakaan tidak 100% jelas dan Anda mendapatkan kepercayaan tentang kontraknya dengan membaca kode sumber, akan sangat masuk akal untuk menegaskan “kontrak yang disimpulkan” tersebut. Jika rusak di versi perpustakaan yang akan datang, Anda akan melihat dengan cepat.
Ini lebih baik daripada solusi berikut yang tidak akan memberi tahu Anda apakah asumsi Anda benar.
Jangan menyalahgunakan pernyataan untuk mengimplementasikan logika program
Penegasan hanya boleh digunakan untuk mengungkap bug yang layak segera membunuh aplikasi Anda. Mereka tidak boleh digunakan untuk memverifikasi kondisi lain apa pun meskipun reaksi yang sesuai dengan kondisi itu juga akan segera dihentikan.
Karena itu, tulis ini ...
... bukannya itu.
Juga tidak pernah menggunakan pernyataan untuk memvalidasi input yang tidak tepercaya atau memeriksa yang
std::malloc
bukanreturn
Andanullptr
. Bahkan jika Anda tahu bahwa Anda tidak akan pernah mematikan pernyataan, bahkan dalam rilis rilis, pernyataan berkomunikasi kepada pembaca bahwa itu memeriksa sesuatu yang selalu benar mengingat bahwa program tersebut bebas bug dan tidak memiliki efek samping yang terlihat. Jika ini bukan jenis pesan yang ingin Anda komunikasikan, gunakan mekanisme penanganan kesalahan alternatif sepertithrow
ing pengecualian. Jika Anda merasa nyaman untuk memiliki pembungkus makro untuk cek non-penegasan Anda, silakan menulis satu. Hanya saja jangan menyebutnya "menegaskan", "menganggap", "mengharuskan", "memastikan" atau sesuatu seperti itu. Logikanya internal bisa sama denganassert
, kecuali bahwa itu tidak pernah dikompilasi, tentu saja.Informasi lebih lanjut
Saya menemukan John Lakos' bicara Defensive Pemrograman Selesai Tepat , diberikan pada CppCon'14 ( 1 st bagian , 2 nd bagian ) sangat mencerahkan. Dia mengambil gagasan untuk menyesuaikan pernyataan apa yang diaktifkan dan bagaimana bereaksi terhadap pengecualian yang gagal bahkan lebih jauh daripada yang saya lakukan dalam jawaban ini.
sumber
Assertions are great, but ... you will turn them off sooner or later.
- Semoga lebih cepat, seperti sebelum kode dikirimkan. Hal-hal yang perlu membuat program mati dalam produksi harus menjadi bagian dari kode "nyata", bukan dalam pernyataan.Saya menemukan bahwa seiring waktu saya menulis lebih sedikit menegaskan karena banyak dari mereka berjumlah "adalah kompiler bekerja" dan "adalah perpustakaan bekerja". Setelah Anda mulai berpikir tentang apa yang sebenarnya Anda uji, saya kira Anda akan menulis lebih sedikit konfirmasi.
Misalnya, metode yang (misalnya) menambahkan sesuatu ke koleksi seharusnya tidak perlu menyatakan bahwa koleksi itu ada - itu umumnya merupakan prasyarat dari kelas yang memiliki pesan atau itu adalah kesalahan fatal yang harus membuatnya kembali ke pengguna . Jadi periksa sekali, sangat awal, lalu anggap itu.
Pernyataan kepada saya adalah alat debugging, dan saya biasanya akan menggunakannya dalam dua cara: menemukan bug di meja saya (dan mereka tidak diperiksa. Yah, mungkin satu kunci yang mungkin); dan menemukan bug di meja pelanggan (dan mereka diperiksa). Kedua kali saya menggunakan pernyataan kebanyakan untuk menghasilkan jejak stack setelah memaksa pengecualian sedini mungkin. Ketahuilah bahwa pernyataan yang digunakan dengan cara ini dapat dengan mudah menyebabkan heisenbug - bug tersebut mungkin tidak pernah terjadi di debug build yang memiliki pernyataan diaktifkan.
sumber
Terlalu sedikit pernyataan: semoga berhasil mengubah kode yang penuh dengan asumsi tersembunyi.
Terlalu banyak asersi: dapat menyebabkan masalah keterbacaan dan berpotensi berbau kode - apakah kelas, fungsi, API dirancang dengan benar ketika memiliki begitu banyak asumsi yang ditempatkan dalam pernyataan yang tegas?
Mungkin ada juga pernyataan yang tidak benar-benar memeriksa apa pun atau memeriksa hal-hal seperti pengaturan kompiler di setiap fungsi: /
Bertujuan untuk sweet spot, tetapi tidak kurang (seperti orang lain sudah mengatakan, "lebih" dari pernyataan kurang berbahaya daripada memiliki terlalu sedikit atau tuhan membantu kita - tidak ada).
sumber
Akan luar biasa jika Anda bisa menulis fungsi Assert yang hanya mengambil referensi ke metode boolean CONST, dengan cara ini Anda yakin bahwa pernyataan Anda tidak memiliki efek samping dengan memastikan bahwa metode const boolean digunakan untuk menguji pernyataan tersebut
itu akan menarik sedikit dari keterbacaan, khususnya karena saya tidak berpikir Anda tidak dapat membuat anotasi lambda (dalam c ++ 0x) untuk menjadi const untuk beberapa kelas, yang berarti Anda tidak dapat menggunakan lambdas untuk itu
berlebihan jika Anda bertanya kepada saya, tetapi jika saya akan mulai melihat tingkat polusi tertentu karena menegaskan saya akan waspada terhadap dua hal:
sumber
Saya telah menulis dalam bahasa C # lebih dari yang saya lakukan di C ++, tetapi kedua bahasa tersebut tidak terlalu berjauhan. Di .Net saya menggunakan Asserts untuk kondisi yang seharusnya tidak terjadi, tetapi saya juga sering melempar pengecualian ketika tidak ada cara untuk melanjutkan. VS2010 debugger menunjukkan kepada saya banyak info bagus tentang pengecualian, tidak peduli seberapa dioptimalkan Rilis build. Anda juga bisa menambahkan tes unit jika memungkinkan. Terkadang logging juga merupakan hal yang baik untuk dimiliki sebagai bantuan debugging.
Jadi, bisakah ada terlalu banyak penegasan? Iya nih. Memilih antara Batalkan / Abaikan / Lanjutkan 15 kali dalam satu menit terasa menyebalkan. Pengecualian hanya dibuang satu kali. Sulit untuk menghitung titik di mana ada terlalu banyak penegasan, tetapi jika pernyataan Anda memenuhi peran penegasan, pengecualian, pengujian unit dan pencatatan, maka ada sesuatu yang salah.
Saya akan memesan pernyataan untuk skenario yang seharusnya tidak terjadi. Anda mungkin terlalu menekankan pada awalnya, karena pernyataan lebih cepat untuk ditulis, tetapi faktor ulang kode nanti - ubah beberapa dari mereka menjadi pengecualian, beberapa menjadi tes, dll. Jika Anda memiliki disiplin yang cukup untuk membersihkan setiap komentar TODO, maka tinggalkan komentar di sebelah masing-masing yang Anda rencanakan untuk dikerjakan ulang, dan JANGAN LUPA untuk membahas TODO nanti.
sumber
Saya ingin bekerja dengan Anda! Seseorang yang banyak menulis
asserts
sangat fantastis. Saya tidak tahu apakah ada yang namanya "terlalu banyak". Jauh lebih umum bagi saya adalah orang-orang yang menulis terlalu sedikit dan akhirnya berakhir dengan masalah UB yang sesekali mematikan yang hanya muncul di bulan purnama yang bisa dengan mudah direproduksi berulang kali dengan sederhanaassert
.Pesan Gagal
Satu hal yang dapat saya pikirkan adalah memasukkan informasi kegagalan ke dalam
assert
jika Anda belum melakukannya, seperti:Dengan cara ini Anda mungkin tidak lagi merasa memiliki terlalu banyak jika Anda belum melakukan ini, karena sekarang Anda membuat pernyataan Anda untuk memainkan peran yang lebih kuat dalam mendokumentasikan asumsi dan prasyarat.
Efek samping
Tentu saja
assert
sebenarnya dapat disalahgunakan dan memperkenalkan kesalahan, seperti:... jika
foo()
memicu efek samping, jadi Anda harus sangat berhati-hati tentang hal itu, tetapi saya yakin Anda sudah sebagai orang yang menyatakan dengan sangat bebas (seorang "asserter berpengalaman"). Semoga prosedur pengujian Anda juga sebaik perhatian Anda untuk menegaskan asumsi.Kecepatan Debugging
Sementara kecepatan debug umumnya harus di bagian bawah daftar prioritas kami, suatu kali saya akhirnya menyatakan begitu banyak dalam basis kode sebelum menjalankan debug membangun melalui debugger lebih dari 100 kali lebih lambat daripada rilis.
Itu terutama karena saya memiliki fungsi seperti ini:
... di mana setiap panggilan tunggal
operator[]
akan melakukan pernyataan batas memeriksa. Saya akhirnya mengganti beberapa yang kritis-kinerja dengan setara yang tidak aman yang tidak menegaskan hanya untuk mempercepat pembangunan debugging secara drastis dengan biaya kecil untuk hanya keselamatan implementasi tingkat detail, dan hanya karena kecepatan mulai itu mulai untuk menurunkan produktivitas dengan sangat nyata (memanfaatkan debugging yang lebih cepat melebihi biaya kehilangan beberapa konfirmasi, tetapi hanya untuk fungsi-fungsi seperti fungsi lintas produk ini yang digunakan dalam jalur yang paling kritis dan terukur, bukan untukoperator[]
secara umum).Prinsip Tanggung Jawab Tunggal
Meskipun saya tidak berpikir Anda bisa benar-benar salah dengan lebih banyak penegasan (setidaknya itu jauh, jauh lebih baik untuk berbuat salah di sisi terlalu banyak daripada terlalu sedikit), menegaskan sendiri mungkin tidak menjadi masalah tetapi mungkin menunjukkan satu.
Jika Anda memiliki 5 pernyataan untuk satu panggilan fungsi, misalnya, itu mungkin terlalu banyak. Antarmukanya mungkin memiliki terlalu banyak prasyarat dan parameter input, mis. Saya menganggap hal itu tidak terkait dengan topik apa yang membentuk sejumlah pernyataan yang sehat (yang biasanya saya tanggapi, "semakin meriah!"), Tetapi itu mungkin saja kemungkinan bendera merah (atau sangat mungkin tidak).
sumber
Sangat masuk akal untuk menambahkan cek ke kode Anda. Untuk pernyataan biasa (yang dibangun ke kompiler C dan C ++) pola penggunaan saya adalah pernyataan gagal berarti ada bug dalam kode yang perlu diperbaiki. Saya menafsirkan ini agak murah hati; jika saya mengharapkan permintaan web untuk kembali status 200 dan menegaskan untuk itu tanpa penanganan kasus lain maka pernyataan gagal melakukan memang menunjukkan bug dalam kode saya, sehingga menegaskan dibenarkan.
Jadi ketika orang mengatakan pernyataan bahwa hanya memeriksa apa yang dilakukan kode itu berlebihan, itu tidak benar. Penegasan itu memeriksa apa yang menurut mereka dilakukan oleh kode, dan inti dari pernyataan tersebut adalah untuk memeriksa bahwa asumsi tidak ada bug dalam kode itu benar. Dan pernyataan itu bisa berfungsi sebagai dokumentasi juga. Jika saya berasumsi bahwa setelah menjalankan loop i == n dan tidak 100% jelas dari kode, maka "menegaskan (i == n)" akan sangat membantu.
Lebih baik memiliki lebih dari sekadar "menegaskan" dalam daftar Anda untuk menangani situasi yang berbeda. Misalnya situasi di mana saya memeriksa bahwa sesuatu tidak terjadi yang akan menunjukkan bug, tetapi masih terus mengatasi kondisi itu. (Misalnya, jika saya menggunakan beberapa cache maka saya mungkin akan memeriksa kesalahan, dan jika kesalahan terjadi secara tak terduga mungkin aman untuk memperbaiki kesalahan dengan membuang cache. Saya ingin sesuatu yang hampir menegaskan, yang memberitahu saya selama pengembangan , dan masih memungkinkan saya melanjutkan.
Contoh lain adalah situasi di mana saya tidak mengharapkan sesuatu terjadi, saya punya solusi generik, tetapi jika hal ini terjadi, saya ingin tahu tentang hal itu dan memeriksanya. Sekali lagi sesuatu yang hampir seperti pernyataan, yang seharusnya memberi tahu saya selama pengembangan. Tapi tidak cukup tegas.
Terlalu banyak pernyataan: Jika suatu pernyataan crash program Anda ketika berada di tangan pengguna, maka Anda tidak boleh memiliki pernyataan yang macet karena negatif palsu.
sumber
Tergantung. Jika persyaratan kode didokumentasikan dengan jelas, maka pernyataan harus selalu sesuai dengan persyaratan. Dalam hal ini adalah hal yang baik. Namun, jika tidak ada persyaratan atau persyaratan yang ditulis dengan buruk, maka akan sulit bagi programmer baru untuk mengedit kode tanpa harus merujuk pada unit test setiap kali untuk mencari tahu apa persyaratannya.
sumber