Apa praktik terbaik untuk menguji program dengan perilaku stokastik?

14

Melakukan penelitian dan pengembangan, saya sering menemukan diri saya menulis program yang memiliki tingkat keacakan yang besar dalam perilaku mereka. Misalnya, ketika saya bekerja di Pemrograman Genetik, saya sering menulis program yang menghasilkan dan mengeksekusi kode sumber acak acak.

Masalah dengan pengujian kode tersebut adalah bahwa bug sering berselang dan bisa sangat sulit untuk mereproduksi. Ini lebih dari sekadar mengatur seed acak ke nilai yang sama dan memulai eksekusi.

Misalnya, kode dapat membaca pesan dari buffer cincin kernal, dan kemudian membuat lompatan bersyarat pada isi pesan. Secara alami, status penyangga cincin akan berubah ketika salah satu dari mereka kemudian mencoba mereproduksi masalah.

Meskipun perilaku ini adalah fitur, ia dapat memicu kode lain dengan cara yang tidak terduga, dan karenanya sering mengungkapkan bug yang tidak ditemukan oleh unit test (atau penguji manusia).

Adakah praktik terbaik yang sudah ada untuk sistem pengujian semacam ini? Jika demikian, beberapa referensi akan sangat membantu. Jika tidak, saran lain dipersilakan!

John Doucette
sumber
5
Tidak bisakah Anda mengejek buffer cincin kernel juga? Dan aspek acak lainnya dari kode Anda?
Jonathan Merlet
1
@ JonathanMerlet Berpotensi, tetapi masalahnya adalah bahwa, ketika digunakan, kode akan memiliki akses ke buffer cincin nyata (memang, ke OS nyata). Jadi jika saya hanya menguji pada versi mocked up, maka saya hanya menunda penemuan bug ini sampai nanti.
John Doucette
Tampaknya bagi saya bahwa masalahnya tidak terkait dengan perilaku acak program (karena ini dapat dikontrol oleh seed acak) tetapi untuk keadaan tertentu dari 'buffer ring kernel' ini. Jadi pertanyaan Anda sebenarnya 'bagaimana cara menguji program yang tergantung pada keadaan eksternal', kan?
AakashM
@ AashashM, ya, itu cara yang lebih baik untuk mengucapkannya. Untuk lebih spesifik, sebuah program dengan status eksternal, yang secara stokastik mengakses atau mengubah status eksternal.
John Doucette

Jawaban:

7

Sangat berguna untuk menambahkan kait, seperti yang disarankan, untuk membuat ulang kondisi yang tepat. Instrumen juga sistem sehingga dapat membuang "bijinya" (dalam kasus Anda, termasuk benih PRNG serta buffer cincin kernel, dan sumber input nondeterministic lainnya.)

Kemudian jalankan pengujian Anda dengan input acak yang benar, dan gaya regresi dengan setiap kasus menarik yang ditemukan sebelumnya.

Dalam kasus khusus akses Anda ke kernel, saya sarankan membuat tiruan dalam hal apa pun. Gunakan tiruan untuk memaksa kelas ekivalensi yang cenderung muncul dalam praktik, dalam semangat "kosong" dan "penuh" untuk wadah, atau "0, 1, 2 ^ n, 2 ^ n + 1, banyak" untuk hal yang dapat dihitung. Kemudian Anda dapat menguji dengan pura-pura dan dengan hal yang nyata, mengetahui bahwa Anda telah menangani dan menguji kasus-kasus yang Anda pikirkan sejauh ini.

Pada dasarnya, apa yang saya sarankan adalah gabungan dari input deterministik dan nondeterministik, dengan yang deterministik adalah campuran dari yang dapat Anda pikirkan dan yang membuat Anda terkejut.

Stephan A. Terre
sumber
6

Satu hal yang masuk akal untuk dilakukan adalah menyemai generator angka acak dengan nilai konstan untuk pengujian, sehingga Anda mendapatkan perilaku deterministik.

Dima
sumber
1
ini; atau mengejek prng sepenuhnya
jk.
1
Terima kasih untuk sarannya! Saya sudah melakukan ini untuk pengujian unit, tetapi saya tidak bisa menguji semua program yang mungkin dilakukan dengan tangan.
John Doucette
2
tetapi ini berarti bahwa Anda tidak dapat menguji apakah keacakan bekerja dengan benar ..
Louis Rhys
2

Saya pikir pengujian statistik adalah satu-satunya cara. Sama seperti angka acak "diuji" untuk keacakan dengan tes statistik, jadi perlu algoritma yang menggunakan perilaku acak.

Cukup jalankan algoritma beberapa kali dengan input yang sama atau berbeda dan bandingkan satu sama lain. Masalah dengan pendekatan ini adalah peningkatan besar dalam waktu komputasi yang diperlukan untuk menyelesaikan pengujian.

Euforia
sumber
Tidak harus, karena Anda dapat memilih satu set input "spanning" kecil dan menjalankannya berkali-kali - jumlah input yang diperlukan untuk memastikan keandalannya mungkin lebih kecil. Set "spanning" ini harus memasukkan setiap cabang kode, menginisialisasi semua objek, dll.
Daniel Moskovich
2

Saya bukan spesialis dalam domain ini, tetapi ada literatur ilmiah relatif terhadap pengujian program stokastik.

Jika Anda tidak dapat dengan mudah membuat kelas tes, tes statistik dapat digunakan, seperti kata #Euphoric. Borning et al. membandingkan pendekatan tradisional dan pendekatan statistik. Generalisasi dari uji statistik yang disarankan oleh @Euphoric bisa menjadi yang dibahas oleh Whittaker. Dia menyarankan untuk membuat model stokastik dari perilaku yang diinginkan (stokastik, dalam kasus Anda) dan kemudian menghasilkan kasus uji khusus dari model ini (lihat makalah khusus nya ).

mgoeminne
sumber
Terima kasih! Terlihat sangat membantu. Bagi lembaga akademis luar tersebut, versi pracetak dari makalah ini dapat ditarik dari repositori kode google penulis di sini: team4model.googlecode.com/svn/trunk/resources/paper/…
John Doucette