Saya baru saja lulus dari perguruan tinggi, dan memulai universitas di suatu tempat minggu depan. Kami telah melihat unit test, tapi kami agak tidak menggunakannya; dan semua orang membicarakannya, jadi saya pikir mungkin saya harus melakukan beberapa.
Masalahnya adalah, saya tidak tahu harus diuji apa . Haruskah saya menguji kasus umum? Kasing tepi? Bagaimana saya tahu bahwa suatu fungsi cukup tertutup?
Saya selalu memiliki perasaan mengerikan bahwa sementara tes akan membuktikan bahwa suatu fungsi berfungsi untuk kasus tertentu, sama sekali tidak berguna untuk membuktikan bahwa fungsi tersebut berfungsi, titik.
Jawaban:
Filosofi pribadi saya sejauh ini adalah:
sumber
Di antara sejumlah besar jawaban sehingga sejauh ini belum ada yang menyentuh pada partisi kesetaraan dan analisis nilai batas , pertimbangan vital dalam jawaban untuk pertanyaan yang ada. Semua jawaban lain, walaupun bermanfaat, bersifat kualitatif tetapi dimungkinkan - dan lebih disukai - untuk menjadi kuantitatif di sini. @fishtoaster memberikan beberapa pedoman konkret, hanya mengintip di bawah selimut kuantifikasi uji, tetapi partisi kesetaraan dan analisis nilai batas memungkinkan kita melakukan yang lebih baik.
Dalam partisi kesetaraan , Anda membagi set semua input yang mungkin menjadi kelompok berdasarkan hasil yang diharapkan. Setiap input dari satu grup akan menghasilkan hasil yang setara, sehingga grup tersebut disebut kelas ekivalensi . (Perhatikan bahwa hasil yang setara tidak berarti hasil yang identik.)
Sebagai contoh sederhana, pertimbangkan program yang harus mengubah karakter ASCII huruf kecil menjadi karakter huruf besar. Karakter lain harus menjalani transformasi identitas, yaitu tetap tidak berubah. Berikut adalah salah satu kemungkinan pengelompokan ke dalam kelas kesetaraan:
Kolom terakhir melaporkan jumlah kasus uji jika Anda menyebutkan semuanya. Secara teknis, dengan aturan @ fishtoaster 1 Anda akan menyertakan 52 kasus uji - semua untuk dua baris pertama yang diberikan di atas termasuk dalam "kasus umum". Aturan @ fishtoaster 2 akan menambahkan beberapa atau semua dari baris 3 dan 4 di atas juga. Tapi dengan kesetaraan partisi menguji setiap satu test case di masing-masing kelas kesetaraan cukup. Jika Anda memilih "a" atau "g" atau "w" Anda sedang menguji jalur kode yang sama. Dengan demikian, Anda memiliki total 4 kasus uji, bukannya 52+.
Analisis nilai batas merekomendasikan sedikit perbaikan: pada dasarnya itu menunjukkan bahwa tidak setiap anggota kelas ekuivalensi, yah, setara. Artinya, nilai pada batas juga harus dianggap layak untuk kasus uji dalam hak mereka sendiri. (Satu pembenaran mudah untuk ini adalah kesalahan off-by-one yang terkenal !) Jadi, untuk setiap kelas ekivalensi Anda dapat memiliki 3 input uji. Melihat domain input di atas - dan dengan sedikit pengetahuan tentang nilai-nilai ASCII - saya mungkin akan menghasilkan input-input kasus uji ini:
(Segera setelah Anda mendapatkan lebih dari 3 nilai batas yang menunjukkan Anda mungkin ingin memikirkan kembali delineasi kelas ekuivalensi asli Anda, tapi ini cukup sederhana sehingga saya tidak kembali untuk merevisinya.) Dengan demikian, analisis nilai batas membawa kita ke hanya 17 kasus uji - dengan tingkat kepercayaan penuh akan cakupan penuh - dibandingkan dengan 128 kasus uji untuk melakukan pengujian lengkap. (Belum lagi bahwa kombinatorik mendikte bahwa pengujian lengkap hanya tidak layak untuk aplikasi dunia nyata!)
sumber
Mungkin pendapat saya tidak terlalu populer. Tetapi saya menyarankan Anda untuk berhemat dengan unit test. Jika Anda memiliki terlalu banyak unit test, Anda dapat dengan mudah menghabiskan setengah dari waktu Anda atau lebih dengan mempertahankan tes daripada coding yang sebenarnya.
Saya menyarankan Anda untuk menulis tes untuk hal-hal yang Anda punya firasat buruk di usus Anda atau hal-hal yang sangat penting dan / atau dasar. Tes unit IMHO bukan pengganti untuk rekayasa yang baik dan pengkodean defensif. Saat ini saya mengerjakan proyek yang kurang lebih tidak dapat digunakan. Ini benar-benar stabil tetapi sakit untuk refactor. Sebenarnya tidak ada yang menyentuh kode ini dalam satu tahun dan tumpukan perangkat lunak yang didasarkan pada adalah 4 tahun. Mengapa? Karena itu berantakan dengan tes unit, tepatnya: Tes unit dan tes integrasi terotomatisasi. (Pernah mendengar mentimun dan sejenisnya?) Dan inilah bagian terbaiknya: Perangkat lunak (yang) tidak dapat digunakan ini telah dikembangkan oleh sebuah perusahaan yang karyawannya adalah pelopor dalam kancah pengembangan yang didorong oleh uji coba. : D
Jadi saran saya adalah:
Mulailah menulis tes setelah Anda mengembangkan kerangka dasar, jika tidak, refactoring bisa menyakitkan. Sebagai pengembang yang mengembangkan untuk orang lain, Anda tidak pernah mendapatkan persyaratan sejak awal.
Pastikan unit test Anda dapat dilakukan dengan cepat. Jika Anda memiliki tes integrasi (seperti mentimun) tidak apa-apa jika perlu waktu lebih lama. Tapi tes berjalan lama tidak menyenangkan, percayalah. (Orang-orang lupa semua alasan mengapa C ++ menjadi kurang populer ...)
Serahkan hal-hal TDD ini kepada para ahli TDD.
Dan ya, kadang-kadang Anda berkonsentrasi pada kasus tepi, kadang-kadang pada kasus umum, tergantung di mana Anda mengharapkan yang tidak terduga. Meskipun jika Anda selalu mengharapkan yang tidak terduga, Anda harus benar-benar memikirkan kembali alur kerja dan disiplin Anda. ;-)
sumber
Leave this TDD stuff to the TDD-experts
.Jika Anda menguji terlebih dahulu dengan Test Driven Development, maka cakupan Anda akan naik di kisaran 90% atau lebih tinggi, karena Anda tidak akan menambahkan fungsionalitas tanpa terlebih dahulu menulis unit test yang gagal untuknya.
Jika Anda menambahkan tes setelah fakta, maka saya tidak bisa merekomendasikan cukup bahwa Anda mendapatkan salinan Bekerja Efektif dengan Kode Legacy oleh Michael Feathers dan lihat beberapa teknik untuk menambahkan tes ke kode Anda dan cara refactoring kode Anda untuk membuatnya lebih dapat diuji.
sumber
The problem is, I don't know _what_ to test
Jika Anda mulai mengikuti praktik Pengembangan yang Didorong oleh Tes , mereka akan menyortir memandu Anda melalui proses dan mengetahui apa yang akan diuji akan muncul secara alami. Beberapa tempat untuk memulai:
Tes didahulukan
Jangan pernah menulis kode sebelum menulis tes. Lihat Red-Green-Refactor-Ulangi untuk penjelasan.
Tulis tes regresi
Setiap kali Anda menemukan bug, tulis testcase, dan pastikan gagal . Kecuali Anda dapat mereproduksi bug melalui testcase yang gagal, Anda belum benar-benar menemukannya.
Merah-Hijau-Refactor-Ulangi
Merah : Mulailah dengan menulis tes paling dasar untuk perilaku yang Anda coba terapkan. Pikirkan langkah ini saat menulis beberapa kode contoh yang menggunakan kelas atau fungsi yang sedang Anda kerjakan. Pastikan ia mengkompilasi / tidak memiliki kesalahan sintaks dan gagal . Ini harus jelas: Anda belum menulis kode apa pun, jadi pasti gagal, bukan? Yang penting untuk dipelajari di sini adalah bahwa kecuali Anda melihat tes gagal setidaknya satu kali, Anda tidak akan pernah yakin bahwa jika lulus, ia melakukannya karena sesuatu yang telah Anda lakukan karena beberapa alasan palsu.
Hijau : Tulis kode paling sederhana dan bodoh yang benar-benar membuat lulus ujian. Jangan mencoba menjadi pintar. Bahkan jika Anda melihat bahwa ada kasus tepi yang jelas tetapi tes memperhitungkan, jangan menulis kode untuk menanganinya (tapi jangan lupa tentang kasus tepi: Anda akan membutuhkannya nanti). Idenya adalah bahwa setiap bagian dari kode yang Anda tulis, setiap
if
, setiaptry: ... except: ...
harus dibenarkan oleh sebuah test case. Kode tidak harus elegan, cepat, atau dioptimalkan. Anda hanya ingin lulus ujian.Refactor : Bersihkan kode Anda, dapatkan nama metode yang benar. Lihat apakah tes masih berlalu. Optimalkan. Jalankan tes lagi.
Ulangi : Anda ingat kasing tepi yang tes tidak menutupi, kan? Jadi, sekarang ini momen besar. Tulis testcase yang mencakup situasi itu, saksikan gagal, tulis beberapa kode, lihat lulus, refactor.
Uji kode Anda
Anda sedang mengerjakan beberapa kode tertentu, dan inilah yang ingin Anda uji. Ini berarti bahwa Anda tidak boleh menguji fungsi perpustakaan, perpustakaan standar atau kompiler Anda. Juga, cobalah untuk menghindari menguji "dunia". Ini termasuk: memanggil API web eksternal, beberapa hal intensif basis data, dll. Setiap kali Anda dapat mencoba mengejanya (buat objek yang mengikuti antarmuka yang sama, tetapi mengembalikan data statis yang telah ditentukan).
sumber
Untuk pengujian unit, mulailah dengan pengujian yang melakukan apa yang dirancang untuk dilakukan. Itu harus menjadi kasus pertama yang Anda tulis. Jika bagian dari desain adalah "harus mengeluarkan pengecualian jika Anda lulus dalam sampah", uji itu juga karena itu adalah bagian dari desain.
Mulailah dengan itu. Ketika Anda mendapatkan pengalaman dengan melakukan hal yang paling mendasar dari pengujian Anda akan mulai belajar apakah itu cukup atau tidak, dan mulai melihat aspek-aspek lain dari kode Anda yang perlu diuji.
sumber
Jawaban utama adalah untuk "menguji segala sesuatu yang mungkin bisa pecah" .
Apa yang terlalu sederhana untuk dihancurkan? Bidang data, pengakses properti mati-otak, dan overhead boilerplate serupa. Hal lain mungkin mengimplementasikan sebagian persyaratan yang dapat diidentifikasi, dan mungkin mendapat manfaat dari pengujian.
Tentu saja, jarak tempuh Anda - dan praktik lingkungan kerja Anda - dapat bervariasi.
sumber