Baik assert dan unit test berfungsi sebagai dokumentasi untuk basis kode, dan sarana untuk menemukan bug. Perbedaan utama adalah bahwa fungsi menegaskan sebagai kewarasan memeriksa dan melihat input nyata, sedangkan tes unit berjalan pada input simulasi spesifik dan merupakan tes terhadap "jawaban benar" tunggal yang jelas. Apa manfaat relatif dari menggunakan tes vs unit test sebagai alat utama memverifikasi kebenaran? Menurut Anda, mana yang harus lebih ditekankan?
testing
unit-testing
assertions
dsimcha
sumber
sumber
:-)
Jawaban:
Sisipan berguna untuk memberi tahu Anda tentang keadaan internal program . Misalnya, bahwa struktur data Anda memiliki status yang valid, misalnya, bahwa
Time
struktur data tidak memiliki nilai25:61:61
. Kondisi yang diperiksa dengan menegaskan adalah:Prasyarat, yang memastikan bahwa penelepon menjaga kontraknya,
Postconditions, yang memastikan bahwa callee menyimpan kontraknya, dan
Invarian, yang memastikan bahwa struktur data selalu memiliki beberapa properti setelah fungsi kembali. Invarian adalah suatu kondisi yang merupakan prasyarat dan postkondisi.
Tes unit berguna untuk memberi tahu Anda tentang perilaku eksternal modul . Anda
Stack
mungkin memiliki status yang konsisten setelahpush()
metode dipanggil, tetapi jika ukuran tumpukan tidak bertambah tiga setelah disebut tiga kali, maka itu adalah kesalahan. (Misalnya, kasus sepele di manapush()
implementasi yang salah hanya memeriksa pernyataan dan keluar.)Sebenarnya, perbedaan utama antara tes menegaskan dan unit adalah tes unit memiliki data uji (nilai untuk menjalankan program), sedangkan menegaskan tidak. Artinya, Anda dapat menjalankan tes unit Anda secara otomatis, sementara Anda tidak dapat mengatakan hal yang sama untuk pernyataan. Demi diskusi ini, saya berasumsi bahwa Anda berbicara tentang mengeksekusi program dalam konteks tes fungsi tingkat tinggi (yang menjalankan seluruh program, dan tidak menggerakkan modul seperti tes unit). Jika Anda tidak berbicara tentang tes fungsi otomatis sebagai sarana untuk "melihat input nyata", maka jelas nilainya terletak pada otomatisasi, dan dengan demikian unit test akan menang. Jika Anda membicarakan hal ini dalam konteks pengujian fungsi (otomatis), lihat di bawah.
Mungkin ada beberapa tumpang tindih dalam apa yang sedang diuji. Sebagai contoh,
Stack
postcondition sebuah sebenarnya dapat menyatakan bahwa ukuran stack meningkat satu. Tetapi ada batas untuk apa yang dapat dilakukan dalam pernyataan itu: Haruskah itu juga memeriksa bahwa elemen atas adalah apa yang baru saja ditambahkan?Untuk keduanya, tujuannya adalah untuk meningkatkan kualitas. Untuk pengujian unit, tujuannya adalah menemukan bug. Untuk pernyataan, tujuannya adalah untuk mempermudah debugging dengan mengamati status program yang tidak valid segera setelah terjadi.
Perhatikan bahwa tidak ada teknik yang memverifikasi kebenaran. Bahkan, jika Anda melakukan pengujian unit dengan tujuan untuk memverifikasi program itu benar, Anda kemungkinan akan datang dengan tes yang tidak menarik yang Anda tahu akan berhasil. Ini adalah efek psikologis: Anda akan melakukan apa pun untuk memenuhi tujuan Anda. Jika tujuan Anda adalah menemukan bug, aktivitas Anda akan mencerminkan hal itu.
Keduanya penting, dan memiliki tujuan masing-masing.
[Sebagai catatan terakhir tentang pernyataan: Untuk mendapatkan nilai maksimal, Anda harus menggunakannya di semua titik kritis dalam program Anda, dan bukan beberapa fungsi utama. Jika tidak, sumber asli masalah mungkin telah ditutup dan sulit dideteksi tanpa berjam-jam melakukan debugging.]
sumber
Saat berbicara tentang asersi, ingatlah bahwa asersi tersebut dapat dimatikan dengan cepat.
Contoh pernyataan yang sangat buruk:
Kenapa ini buruk? Karena tidak ada pengecekan kesalahan yang dilakukan jika pernyataan dilewati karena sesuatu seperti NDEBUG didefinisikan.
Tes unit akan (kemungkinan) hanya memisahkan pada kode di atas. Tentu, itu melakukan tugasnya dengan memberi tahu Anda bahwa ada yang salah, atau bukan? Seberapa besar kemungkinan
malloc()
gagal dalam ujian?Pernyataan adalah untuk tujuan debugging ketika seorang programmer perlu menyiratkan bahwa tidak ada kejadian 'normal' yang akan menyebabkan pernyataan tersebut untuk menyala.
malloc()
gagal adalah, memang peristiwa yang normal, dengan demikian tidak boleh ditegaskan.Ada banyak kasus lain di mana pernyataan digunakan alih-alih secara memadai menangani hal-hal yang mungkin salah. Inilah sebabnya mengapa pernyataan mendapatkan reputasi buruk, dan mengapa bahasa seperti Go tidak memasukkannya.
Tes unit dirancang untuk memberi tahu Anda ketika sesuatu yang Anda ubah merusak sesuatu yang lain. Mereka dirancang untuk menghemat (dalam banyak kasus) akan melalui setiap fitur dari program ini (Namun, penguji yang penting untuk rilis) setiap kali Anda membuat sebuah build.
Sebenarnya tidak ada korelasi yang jelas di antara keduanya, selain keduanya memberi tahu Anda bahwa ada yang salah. Pikirkan penegasan sebagai breakpoint dalam sesuatu yang sedang Anda kerjakan, tanpa harus menggunakan debugger. Pikirkan unit test sebagai sesuatu yang memberi tahu Anda jika Anda memecahkan sesuatu yang tidak Anda kerjakan.
sumber
Keduanya adalah alat yang digunakan untuk membantu meningkatkan kualitas keseluruhan sistem yang Anda bangun. Banyak tergantung pada bahasa yang Anda gunakan, jenis aplikasi yang Anda buat, dan di mana waktu Anda dihabiskan. Belum lagi Anda memiliki beberapa aliran pemikiran tentang hal itu.
Untuk memulainya, jika Anda menggunakan bahasa tanpa
assert
kata kunci, Anda tidak bisa menggunakan kata keterangan (setidaknya tidak dengan cara kita berbicara di sini). Untuk waktu yang lama, Java tidak memilikiassert
kata kunci, dan sejumlah bahasa masih belum. Unit testing kemudian menjadi sedikit lebih penting. Dalam beberapa bahasa pernyataan hanya dijalankan ketika bendera diatur (lagi dengan Java di sini). Ketika perlindungan tidak selalu ada, itu bukan fitur yang sangat berguna.Ada aliran pemikiran yang mengatakan jika Anda "menegaskan" sesuatu, Anda mungkin juga menulis blok pengecualian
if
/throw
bermakna. Proses pemikiran ini berasal dari banyak pernyataan yang ditempatkan di awal metode untuk memastikan semua nilai terikat. Menguji prasyarat Anda adalah bagian yang sangat penting untuk mendapatkan kondisi pascakemudian yang diharapkan.Pengujian unit adalah kode tambahan yang harus ditulis dan dipelihara. Bagi banyak orang ini adalah kelemahan. Namun, dengan pemotongan kerangka kerja unit test saat ini di luar sana, Anda dapat menghasilkan sejumlah besar kondisi pengujian dengan kode yang relatif sedikit. Tes parameter dan "teori" akan melakukan tes yang sama dengan sejumlah besar sampel data yang dapat mengungkap beberapa bug yang sulit ditemukan.
Saya pribadi menemukan saya mendapatkan lebih banyak jarak tempuh dengan pengujian unit daripada percikan, tetapi itu karena platform yang saya kembangkan pada sebagian besar waktu (Java / C #). Bahasa lain memiliki dukungan pernyataan yang lebih kuat, dan bahkan "Desain dengan Kontrak" (lihat di bawah) untuk memberikan lebih banyak jaminan. Jika saya bekerja dengan salah satu bahasa ini, saya mungkin menggunakan DBC lebih dari pengujian unit.
http://en.wikipedia.org/wiki/Design_by_contract#Languages_with_native_support
sumber