Saya memiliki rekan kerja yang menulis pengujian unit untuk objek yang mengisi bidangnya dengan data acak. Alasannya adalah memberikan pengujian yang lebih luas, karena akan menguji banyak nilai yang berbeda, sedangkan pengujian normal hanya menggunakan satu nilai statis.
Saya telah memberinya sejumlah alasan berbeda untuk melawan ini, yang utama adalah:
- nilai acak berarti pengujian tidak benar-benar dapat diulang (yang juga berarti bahwa jika pengujian dapat gagal secara acak, pengujian dapat dilakukan di server build dan merusak build)
- jika itu adalah nilai acak dan pengujian gagal, kita perlu a) memperbaiki objek dan b) memaksa diri kita sendiri untuk menguji nilai itu setiap saat, jadi kita tahu itu berhasil, tetapi karena ini acak kita tidak tahu apa nilainya
Rekan kerja lain menambahkan:
- Jika saya menguji pengecualian, nilai acak tidak akan memastikan bahwa pengujian berakhir dalam keadaan yang diharapkan
- data acak digunakan untuk membersihkan sistem dan pengujian beban, bukan untuk pengujian unit
Adakah yang bisa menambahkan alasan tambahan yang bisa saya berikan padanya untuk membuatnya berhenti melakukan ini?
(Atau sebaliknya, apakah ini metode penulisan tes unit yang dapat diterima, dan saya serta rekan kerja saya yang lain salah?)
unit-testing
tdd
mocking
Adam V
sumber
sumber
Jawaban:
Ada kompromi. Rekan kerja Anda sebenarnya tertarik pada sesuatu, tetapi saya pikir dia salah melakukannya. Saya tidak yakin bahwa pengujian yang benar-benar acak sangat berguna, tetapi tentu saja tidak valid.
Spesifikasi program (atau unit) adalah hipotesis bahwa terdapat beberapa program yang memenuhi itu. Program itu sendiri kemudian menjadi bukti hipotesis itu. Pengujian unit yang seharusnya adalah upaya untuk memberikan bukti tandingan untuk menyangkal bahwa program bekerja sesuai dengan spesifikasi.
Sekarang, Anda dapat menulis pengujian unit dengan tangan, tetapi ini benar-benar merupakan tugas mekanis. Itu bisa otomatis. Yang harus Anda lakukan adalah menulis spesifikasi, dan mesin dapat menghasilkan banyak sekali pengujian unit yang mencoba memecahkan kode Anda.
Saya tidak tahu bahasa apa yang Anda gunakan, tapi lihat di sini:
Java http://functionaljava.org/
Scala (atau Java) http://github.com/rickynils/scalacheck
Haskell http://www.cs.chalmers.se/~rjmh/QuickCheck/
.NET: http://blogs.msdn.com/dsyme/archive/2008/08/09/fscheck-0-2.aspx
Alat-alat ini akan mengambil spesifikasi Anda yang telah dibentuk dengan baik sebagai masukan dan secara otomatis menghasilkan pengujian unit sebanyak yang Anda inginkan, dengan data yang dibuat secara otomatis. Mereka menggunakan strategi "menyusut" (yang dapat Anda sesuaikan) untuk menemukan kasus uji yang paling sederhana untuk memecahkan kode Anda dan untuk memastikannya mencakup kasus tepi dengan baik.
Selamat menguji!
sumber
Jenis pengujian ini disebut pengujian Monkey . Jika dilakukan dengan benar, itu bisa mengeluarkan serangga dari sudut yang benar-benar gelap.
Untuk mengatasi kekhawatiran Anda tentang reproduktifitas: cara yang tepat untuk melakukan ini, adalah dengan merekam entri tes yang gagal, menghasilkan tes unit, yang menyelidiki seluruh keluarga dari bug tertentu; dan termasuk dalam pengujian unit satu input spesifik (dari data acak) yang menyebabkan kegagalan awal.
sumber
Ada rumah singgah di sini yang memiliki beberapa kegunaan, yaitu untuk menyemai PRNG Anda dengan konstan. Itu memungkinkan Anda untuk menghasilkan data 'acak' yang dapat diulang.
Secara pribadi saya pikir ada tempat di mana data acak (konstan) berguna dalam pengujian - setelah Anda pikir Anda telah melakukan semua sudut yang dipikirkan dengan cermat, menggunakan rangsangan dari PRNG terkadang dapat menemukan hal-hal lain.
sumber
Dalam buku Beautiful Code , ada bab yang berjudul "Beautiful Tests", di mana dia membahas strategi pengujian untuk algoritma Binary Search . Satu paragraf disebut "Tindakan Pengujian Acak", di mana dia membuat susunan acak untuk menguji algoritme secara menyeluruh. Anda dapat membaca beberapa di antaranya secara online di Google Buku, halaman 95 , tetapi ini adalah buku yang sangat berharga.
Jadi pada dasarnya ini hanya menunjukkan bahwa menghasilkan data acak untuk pengujian adalah opsi yang layak.
sumber
Saya mendukung tes acak, dan saya menulisnya. Namun, apakah mereka sesuai dalam lingkungan build tertentu dan suite pengujian mana yang harus disertakan adalah pertanyaan yang lebih bernuansa.
Jalankan secara lokal (misalnya, semalaman di kotak dev Anda) tes acak telah menemukan bug yang jelas dan tidak jelas. Yang tidak jelas cukup misterius sehingga saya pikir pengujian acak benar-benar satu-satunya yang realistis untuk menghilangkannya. Sebagai ujian, saya mengambil satu bug yang sulit ditemukan yang ditemukan melalui pengujian acak dan meminta setengah lusin pengembang crack meninjau fungsi (sekitar selusin baris kode) tempat terjadinya. Tidak ada yang bisa mendeteksinya.
Banyak argumen Anda terhadap data acak adalah bentuk dari "pengujian tidak dapat direproduksi". Namun, tes acak yang ditulis dengan baik akan menangkap benih yang digunakan untuk memulai benih acak dan mengeluarkannya jika gagal. Selain memungkinkan Anda mengulangi pengujian dengan tangan, ini memungkinkan Anda membuat pengujian baru yang menguji masalah tertentu secara mudah dengan melakukan hardcode seed untuk pengujian tersebut. Tentu saja, mungkin lebih baik untuk memberi kode tangan pada tes eksplisit yang mencakup kasus itu, tetapi kemalasan memiliki kelebihan, dan ini bahkan memungkinkan Anda untuk secara otomatis menghasilkan kasus uji baru dari seed yang gagal.
Namun, satu hal yang Anda buat yang tidak dapat saya perdebatkan adalah bahwa hal itu merusak sistem build. Sebagian besar pengujian build dan continuous integration mengharapkan pengujian melakukan hal yang sama, setiap saat. Jadi tes yang gagal secara acak akan menciptakan kekacauan, gagal secara acak dan menunjukkan perubahan yang tidak berbahaya.
Solusinya adalah dengan tetap menjalankan pengujian acak Anda sebagai bagian dari pengujian build dan CI, tetapi menjalankannya dengan seed tetap, untuk sejumlah iterasi tetap . Oleh karena itu, pengujian selalu melakukan hal yang sama, tetapi masih mengeksplorasi sekumpulan ruang input (jika Anda menjalankannya untuk beberapa iterasi).
Secara lokal, misalnya, saat mengubah kelas terkait, Anda bebas menjalankannya untuk lebih banyak iterasi atau dengan seed lain. Jika pengujian acak menjadi lebih populer, Anda bahkan dapat membayangkan rangkaian pengujian tertentu yang diketahui acak, yang dapat dijalankan dengan benih yang berbeda (karenanya dengan cakupan yang meningkat dari waktu ke waktu), dan di mana kegagalan tidak berarti hal yang sama sebagai sistem CI deterministik (yaitu, proses tidak terkait 1: 1 dengan perubahan kode sehingga Anda tidak perlu menunjuk perubahan tertentu ketika ada yang gagal).
Ada banyak hal yang bisa dikatakan tentang tes acak, terutama tes yang ditulis dengan baik, jadi jangan terlalu cepat mengabaikannya!
sumber
Jika Anda melakukan TDD maka saya berpendapat bahwa data acak adalah pendekatan yang sangat baik. Jika pengujian Anda ditulis dengan konstanta, Anda hanya dapat menjamin kode Anda berfungsi untuk nilai tertentu. Jika pengujian Anda gagal secara acak server build, kemungkinan ada masalah dengan cara pengujian ditulis.
Data acak akan membantu memastikan pemfaktoran ulang di masa mendatang tidak akan bergantung pada konstanta ajaib. Lagi pula, jika pengujian Anda adalah dokumentasi Anda, bukankah keberadaan konstanta menyiratkan bahwa hanya perlu berfungsi untuk konstanta tersebut?
Saya melebih-lebihkan namun saya lebih suka menyuntikkan data acak ke dalam pengujian saya sebagai tanda bahwa "nilai variabel ini seharusnya tidak memengaruhi hasil pengujian ini".
Saya akan mengatakan bahwa jika Anda menggunakan variabel acak kemudian membagi tes Anda berdasarkan variabel itu, maka itu adalah bau.
sumber
Rekan kerja Anda sedang melakukan pengujian fuzz , meskipun dia tidak mengetahuinya. Mereka sangat berharga dalam sistem server.
sumber
Satu keuntungan bagi seseorang yang melihat tes adalah bahwa data yang berubah-ubah jelas tidak penting. Saya telah melihat terlalu banyak tes yang melibatkan lusinan potongan data dan sulit untuk mengatakan apa yang perlu dilakukan seperti itu dan apa yang kebetulan seperti itu. Misalnya, jika metode validasi alamat diuji dengan kode pos tertentu dan semua data lainnya acak, maka Anda dapat yakin bahwa kode pos adalah satu-satunya bagian penting.
sumber
Jika kasus pengujian Anda tidak secara akurat mencatat apa yang diuji, mungkin Anda perlu membuat kode ulang kasus pengujian. Saya selalu ingin memiliki log yang dapat saya rujuk kembali untuk kasus pengujian sehingga saya tahu persis apa yang menyebabkannya gagal apakah menggunakan data statis atau acak.
sumber
Dapatkah Anda menghasilkan beberapa data acak sekali (maksud saya persis sekali, bukan sekali per uji coba), lalu menggunakannya di semua pengujian setelahnya?
Saya pasti dapat melihat nilai dalam membuat data acak untuk menguji kasus-kasus yang belum Anda pikirkan, tetapi Anda benar, memiliki pengujian unit yang dapat lulus atau gagal secara acak adalah hal yang buruk.
sumber
Anda harus bertanya pada diri sendiri apa tujuan ujian Anda.
Tes unit adalah tentang memverifikasi logika, aliran kode, dan interaksi objek. Menggunakan nilai acak mencoba mencapai tujuan yang berbeda, sehingga mengurangi fokus pengujian dan kesederhanaan. Ini dapat diterima karena alasan keterbacaan (menghasilkan UUID, id, kunci, dll.).
Khusus untuk unit test, saya tidak dapat mengingatnya walaupun metode ini berhasil menemukan masalah. Tetapi saya telah melihat banyak masalah determinisme (dalam tes) mencoba menjadi pandai dengan nilai acak dan terutama dengan tanggal acak.
Pengujian fuzz adalah pendekatan yang valid untuk pengujian integrasi dan pengujian ujung ke ujung .
sumber
Jika Anda menggunakan input acak untuk pengujian Anda, Anda perlu mencatat input sehingga Anda dapat melihat nilainya. Dengan cara ini jika ada kasus tepi yang Anda temui, Anda dapat menulis tes untuk mereproduksinya. Saya pernah mendengar alasan yang sama dari orang-orang untuk tidak menggunakan input acak, tetapi begitu Anda memiliki wawasan tentang nilai aktual yang digunakan untuk uji coba tertentu, itu bukan masalah yang besar.
Pengertian “sembarang” data juga sangat berguna sebagai cara menandakan sesuatu yang tidak penting. Kami memiliki beberapa tes penerimaan yang terlintas dalam pikiran di mana ada banyak data gangguan yang tidak relevan dengan tes yang ada.
sumber
Bergantung pada objek / aplikasi Anda, data acak akan memiliki tempat dalam pengujian beban. Saya pikir yang lebih penting adalah menggunakan data yang secara eksplisit menguji kondisi batas data.
sumber
Kami baru saja mengalami ini hari ini. Saya ingin pseudo-random (jadi akan terlihat seperti data audio terkompresi dalam hal ukuran). Saya TODO bahwa saya juga ingin deterministik . rand () berbeda di OSX daripada di Linux. Dan kecuali saya melakukan seeding ulang, itu bisa berubah kapan saja. Jadi kami mengubahnya menjadi deterministik tetapi tetap psuedo-random: pengujian ini dapat diulangi, sama seperti menggunakan data kaleng (tetapi lebih mudah ditulis).
Ini BUKAN diuji oleh beberapa kekerasan acak melalui jalur kode. Itulah perbedaannya: masih deterministik, masih berulang, masih menggunakan data yang terlihat seperti input nyata untuk menjalankan serangkaian pemeriksaan menarik pada kasus edge dalam logika yang kompleks. Masih unit tes.
Apakah yang masih memenuhi syarat itu acak? Mari kita bicara tentang bir. :-)
sumber
Saya dapat membayangkan tiga solusi untuk masalah data pengujian:
Saya akan merekomendasikan melakukan semua hal di atas . Artinya, tulis pengujian unit yang dapat diulang dengan kedua kasus tepi bekerja menggunakan otak Anda, dan beberapa data acak yang Anda buat hanya sekali. Kemudian tulis serangkaian pengujian acak yang Anda jalankan juga .
Tes acak tidak boleh diharapkan untuk menangkap sesuatu yang luput dari tes berulang Anda. Anda harus bertujuan untuk mencakup semuanya dengan tes berulang, dan menganggap tes acak sebagai bonus. Jika mereka menemukan sesuatu, itu haruslah sesuatu yang tidak dapat Anda prediksi secara masuk akal; eksentrik yang nyata.
sumber
Bagaimana cowok Anda bisa menjalankan tes lagi ketika gagal untuk melihat apakah dia telah memperbaikinya? Yaitu dia kehilangan pengulangan tes.
Meskipun saya pikir mungkin ada beberapa nilai dalam melemparkan beban data acak pada pengujian, seperti yang disebutkan dalam balasan lain, hal itu lebih termasuk dalam judul pengujian beban daripada yang lainnya. Ini adalah praktik "menguji dengan harapan". Saya pikir, pada kenyataannya, pria Anda sama sekali tidak memikirkan tentang apa yang dia coba uji, dan mengganti kekurangan pemikiran itu dengan berharap keacakan pada akhirnya akan menjebak beberapa kesalahan misterius.
Jadi argumen yang akan saya gunakan dengannya adalah bahwa dia malas. Atau, dengan kata lain, jika dia tidak meluangkan waktu untuk memahami apa yang dia coba uji, itu mungkin menunjukkan dia tidak benar-benar memahami kode yang dia tulis.
sumber
while(true)
putaran dan kemungkinan besar akan gagal dalam waktu yang diperlukan untuk memeriksa Anda. umpan snapchat.