Kita tahu bahwa menulis tes JUnit menunjukkan satu jalur tertentu melalui kode Anda.
Salah satu rekan saya berkomentar:
Tes unit yang ditulis secara manual adalah Proof By Example .
Dia berasal dari latar belakang Haskell yang memiliki alat seperti Quickcheck dan kemampuan untuk berpikir tentang perilaku program dengan tipe .
Implikasinya adalah bahwa ada banyak kombinasi input lain yang belum dicoba oleh metode ini yang kode Anda tidak diuji.
Pertanyaan saya adalah: Apakah penulisan unit secara manual membuktikan dengan contoh?
unit-testing
junit
hawkeye
sumber
sumber
Jawaban:
Jika Anda secara acak memilih input untuk pengujian, maka saya kira itu mungkin bahwa Anda menggunakan Bukti dengan Contoh yang salah.
Tetapi unit test yang baik tidak pernah melakukan itu. Sebaliknya, mereka menangani rentang dan tepi kasus.
Misalnya, jika Anda menulis tes unit untuk fungsi nilai absolut yang menerima integer sebagai input, Anda tidak perlu menguji setiap nilai input yang mungkin untuk membuktikan bahwa kode berfungsi. Untuk mendapatkan tes komprehensif, Anda hanya perlu lima nilai: -1, 0, 1, dan nilai maks dan min untuk bilangan bulat input.
Kelima nilai ini menguji setiap kemungkinan rentang dan tepi kasus fungsi. Anda tidak perlu menguji setiap nilai input yang mungkin lainnya (yaitu setiap angka yang dapat diwakili oleh tipe integer) untuk mendapatkan tingkat kepercayaan tinggi bahwa fungsi tersebut bekerja untuk semua nilai input.
sumber
int foo(int x) { return 1234/(x - 100); }
. Perhatikan juga bahwa (tergantung pada apa yang Anda uji), Anda mungkin perlu memastikan bahwa input yang tidak valid ("di luar jangkauan") mengembalikan hasil yang benar (mis. `` Find_thing (thing) `dengan benar mengembalikan semacam status" tidak ditemukan "dengan benar jika benda itu tidak ditemukan).-Inf
,Inf
,NaN
,1e-100
,-1e-100
,-0
,2e200
... aku lebih suka tidak perlu melakukan hal-semua secara manual.Setiap pengujian perangkat lunak seperti "Bukti Dengan Contoh", tidak hanya pengujian unit menggunakan alat seperti JUnit. Dan itu bukan kebijaksanaan baru, ada kutipan dari Dijkstra dari tahun 1960, yang pada dasarnya mengatakan hal yang sama:
(cukup ganti kata "menunjukkan" dengan "bukti"). Namun, ini juga berlaku untuk alat yang menghasilkan data uji acak. Jumlah input yang mungkin untuk fungsi dunia nyata biasanya lebih besar berdasarkan urutan besarnya daripada jumlah kasus uji yang dapat dihasilkan dan diverifikasi terhadap hasil yang diharapkan dalam usia alam semesta, terlepas dari metode pembuatan kasus tersebut, jadi bahkan jika seseorang menggunakan alat generator untuk menghasilkan banyak data pengujian, tidak ada jaminan untuk tidak melewatkan satu test case yang dapat mendeteksi bug tertentu.
Tes acak terkadang dapat mengungkapkan bug yang diabaikan oleh kasus uji yang dibuat secara manual. Tetapi secara umum, lebih efisien untuk membuat tes dengan hati-hati terhadap fungsi yang akan diuji, dan memastikan seseorang mendapatkan kode lengkap dan cakupan cabang dengan sesedikit mungkin kasus uji. Kadang-kadang itu adalah strategi yang layak untuk menggabungkan tes yang dihasilkan secara manual dan acak. Terlebih lagi, ketika menggunakan tes acak, seseorang harus berhati-hati untuk mendapatkan hasilnya secara berulang.
Jadi tes yang dibuat secara manual sama sekali tidak lebih buruk daripada tes yang dibuat secara acak, seringkali justru sebaliknya.
sumber
Tes menulis secara manual adalah "bukti dengan contoh". Tapi begitu juga QuickCheck, dan untuk sistem tipe terbatas. Apa pun yang bukan verifikasi formal langsung akan dibatasi dalam hal yang memberi tahu Anda tentang kode Anda. Sebaliknya, Anda harus berpikir dalam kaitannya dengan manfaat relatif dari pendekatan.
Pengujian generatif, seperti QuickCheck, sangat bagus untuk menyapu ruang input yang luas. Ini juga jauh lebih baik untuk menangani kasus tepi daripada tes manual: perpustakaan pengujian generatif akan lebih berpengalaman dengan ini daripada Anda. Di sisi lain, mereka hanya memberi tahu Anda tentang invarian, bukan output spesifik. Jadi untuk memvalidasi program Anda mendapatkan hasil yang benar, Anda masih memerlukan beberapa tes manual untuk memverifikasi itu, pada kenyataannya
foo(bar) = baz
,.sumber