Pengujian unit hanya berguna jika menguji implementasi yang benar dari fungsi tersebut, bukan penggunaan yang benar, karena pengujian unit tidak dapat mengatakan bahwa suatu fungsi tidak akan dipanggil dari utas lain di seluruh basis kode Anda, seperti yang bisa dilakukan ' t mengatakan bahwa fungsi tidak akan dipanggil dengan parameter yang melanggar prasyaratnya (dan secara teknis apa yang Anda coba uji pada dasarnya merupakan pelanggaran prasyarat dalam penggunaan, yang merupakan sesuatu yang tidak dapat Anda uji secara efektif karena tes dapat ' t membatasi cara tempat lain dalam basis kode menggunakan fungsi tersebut; Anda dapat menguji apakah pelanggaran terhadap prasyarat menghasilkan kesalahan / pengecualian yang wajar, namun).
Ini adalah kasus penegasan bagi saya dalam implementasi fungsi yang relevan sendiri seperti yang beberapa orang lain tunjukkan, atau bahkan lebih canggih adalah untuk memastikan fungsi tersebut aman dari thread (meskipun ini tidak selalu praktis ketika bekerja dengan beberapa API).
Juga hanya catatan samping tapi "utas utama"! = "Utas UI" dalam semua kasus. Banyak API GUI yang tidak aman-utas (dan membuat kit GUI yang aman-utas sangat sulit), tetapi itu tidak berarti Anda harus memintanya dari utas yang sama dengan yang memiliki titik masuk untuk aplikasi Anda. Itu mungkin berguna bahkan dalam mengimplementasikan pernyataan Anda di dalam fungsi UI yang relevan untuk membedakan "utas UI" dari "utas utama", seperti menangkap ID utas saat ini ketika sebuah jendela dibuat untuk dibandingkan dengan bukan dari titik masuk utama aplikasi (yang setidaknya mengurangi jumlah asumsi / batasan penggunaan yang diterapkan hanya oleh apa yang benar-benar relevan).
Keamanan benang sebenarnya adalah titik pijakan "gotcha" di bekas tim saya, dan dalam kasus khusus kami, saya akan menyebutnya sebagai "optimasi mikro" yang paling kontra-produktif di antara mereka semua yang menghasilkan lebih banyak biaya perawatan daripada rakitan tulisan tangan. Kami memiliki cakupan kode yang agak komprehensif dalam pengujian unit kami, bersama dengan tes integrasi yang agak canggih, hanya untuk menghadapi kebuntuan dan kondisi balapan dalam perangkat lunak yang menghindari pengujian kami. Dan itu karena pengembang kode multithreaded sembarangan tanpa menyadari setiap efek samping yang mungkin terjadi dalam rantai panggilan fungsi yang akan dihasilkan dari mereka sendiri, dengan ide yang agak naif bahwa mereka dapat memperbaiki bug tersebut di belakang dengan hanya melempar mengunci di kiri dan kanan,
Saya condong ke arah yang berlawanan sebagai tipe sekolah tua yang tidak mempercayai multithreading, adalah orang yang benar-benar terlambat untuk merangkulnya, dan berpikir kebenaran mengalahkan kinerja hingga jarang sekali menggunakan semua core yang kita miliki sekarang, sampai saya menemukan hal-hal seperti fungsi murni dan desain yang tidak berubah dan struktur data yang gigih yang akhirnya memungkinkan saya untuk sepenuhnya menggunakan perangkat keras itu tanpa khawatir di dunia tentang kondisi balapan dan kebuntuan. Saya harus mengakui bahwa sepanjang jalan hingga 2010 atau lebih, saya benci multithreading dengan penuh semangat kecuali untuk beberapa loop paralel di sana-sini di daerah-daerah yang sepele dengan alasan keamanan benang, dan lebih menyukai kode yang lebih berurutan untuk desain produk yang diberikan kesedihan saya dengan multithreading di bekas tim.
Bagi saya cara multithreading yang pertama dan memperbaiki bug kemudian adalah strategi yang mengerikan untuk multithreading sampai hampir membuat saya membenci multithreading pada awalnya; Anda juga memastikan desain Anda aman dari benang-solid dan implementasinya hanya menggunakan fungsi dengan jaminan yang sama (mis: fungsi murni), atau Anda menghindari multithreading. Itu mungkin sedikit dogmatis tetapi mengalahkan menemukan (atau lebih buruk, tidak menemukan) masalah yang sulit untuk direproduksi di belakang yang menghindari tes. Tidak ada gunanya mengoptimalkan mesin roket jika itu akan membuatnya rentan meledak tiba-tiba di tengah jalan sepanjang perjalanannya menuju ruang angkasa.
Jika Anda mau tidak mau harus bekerja dengan kode yang tidak aman thread, maka saya tidak melihat itu sebagai masalah untuk diselesaikan dengan pengujian unit / integrasi begitu banyak. Yang ideal adalah membatasi akses . Jika kode GUI Anda dipisahkan dari logika bisnis, maka Anda mungkin dapat menerapkan desain yang membatasi akses ke panggilan tersebut dari apa pun selain utas / objek yang membuatnya *. Mode yang jauh ideal bagi saya adalah membuatnya tidak mungkin untuk utas lain memanggil fungsi-fungsi itu daripada mencoba memastikannya tidak.
- Ya, saya menyadari bahwa selalu ada cara di sekitar batasan desain apa pun yang Anda tegakkan secara khusus di mana kompiler tidak dapat melindungi Anda. Saya hanya berbicara secara praktis; jika Anda bisa mengabstraksi objek "GUI Thread" atau apa pun, maka itu mungkin satu-satunya yang menyerahkan parameter ke objek / fungsi GUI, dan Anda mungkin dapat membatasi objek tersebut dari memiliki akses ke utas lainnya. Tentu saja mungkin dapat memotong dan menggali lebih dalam dan bekerja di sekitar lingkaran untuk melewati fungsi / objek GUI ke utas lainnya untuk memohon, tetapi setidaknya ada penghalang di sana, dan Anda dapat memanggil siapa saja yang melakukan itu "idiot ", dan tidak salah, paling tidak, karena dengan jelas melewati dan mencari celah untuk apa yang jelas-jelas ingin dibatasi oleh desain. :-D Itu