Saya benar-benar jatuh cinta dengan pengujian unit dan TDD - Saya tes terinfeksi.
Namun, pengujian unit biasanya digunakan untuk metode publik. Kadang-kadang meskipun saya harus menguji beberapa asumsi-pernyataan dalam metode pribadi juga, karena beberapa dari mereka "berbahaya" dan refactoring tidak dapat membantu lebih lanjut. (Saya tahu, kerangka pengujian memungkinkan pengujian metode pribadi).
Jadi sudah menjadi kebiasaan saya bahwa baris pertama dan terakhir dari metode pribadi adalah pernyataan.
Namun, saya perhatikan bahwa saya cenderung menggunakan pernyataan dalam metode publik (dan juga pribadi) hanya "untuk memastikan". Mungkinkah ini "pengujian duplikasi" karena asumsi metode publik diuji dari luar oleh kerangka pengujian unit?
Bisakah seseorang menganggap terlalu banyak pernyataan sebagai bau kode?
sumber
Jawaban:
Pernyataan itu sangat berguna untuk menguji asumsi Anda, tetapi mereka juga melayani tujuan lain yang sangat penting: dokumentasi. Setiap pembaca dari metode publik dapat membaca pernyataan untuk dengan cepat menentukan kondisi sebelum dan sesudah, tanpa harus melihat test suite. Untuk alasan ini, saya sarankan Anda menyimpan pernyataan itu untuk alasan dokumentasi, daripada alasan pengujian. Secara teknis Anda menduplikasi pernyataan, tetapi mereka melayani dua tujuan yang berbeda dan sangat berguna dalam keduanya.
Menjaga mereka sebagai pernyataan lebih baik daripada hanya menggunakan komentar, karena mereka secara aktif memeriksa asumsi setiap kali dijalankan.
sumber
Sepertinya Anda mencoba melakukan Desain-dengan-Kontrak dengan tangan.
Melakukan DbC adalah ide yang bagus, tetapi Anda setidaknya harus mempertimbangkan beralih ke bahasa yang mendukungnya secara native (seperti Eiffel ) atau setidaknya menggunakan kerangka kontrak untuk platform Anda (misalnya Kontrak Kode Microsoft untuk .NETcukup bagus, bisa dibilang kerangka kontrak paling canggih di luar sana, bahkan lebih kuat dari Eiffel). Dengan begitu, Anda dapat lebih memanfaatkan kekuatan kontrak. Misalnya menggunakan kerangka kerja yang ada, Anda dapat memunculkan kontrak dalam dokumentasi Anda atau IDE (mis. Kontrak Kode untuk .NET ditunjukkan dalam IntelliSense dan, jika Anda memiliki VS Ultimate, bahkan dapat diperiksa secara statis oleh teorema teorema otomatis pada waktu kompilasi sementara Anda mengetik; demikian juga banyak kerangka kontrak Java memiliki doclet JavaDoc yang secara otomatis akan mengekstrak kontrak ke dalam dokumentasi JavaDoc API Anda).
Dan bahkan jika ternyata dalam situasi Anda tidak ada alternatif untuk melakukannya secara manual, Anda sekarang setidaknya tahu apa namanya, dan dapat membacanya.
Jadi, singkatnya: jika Anda memang melakukan DbC, bahkan jika Anda tidak mengetahuinya, maka pernyataan itu baik-baik saja.
sumber
Setiap kali Anda tidak memiliki kendali penuh atas parameter input Anda, itu ide yang sangat bagus untuk menguji di muka untuk kesalahan sederhana. Gagal pada nol misalnya.
Ini bukan duplikasi tes Anda, karena mereka harus menguji bahwa kode gagal tepat diberikan parameter input yang buruk, dan kemudian mendokumentasikan bahwa .
Saya tidak berpikir Anda harus menegaskan pada parameter kembali (kecuali jika Anda secara eksplisit memiliki invarian Anda ingin pembaca mengerti). Ini juga merupakan tugas para unittests.
Secara pribadi saya tidak suka
assert
pernyataan di Jawa, karena mereka dapat dimatikan dan kemudian itu adalah keamanan palsu.sumber
Saya pikir menggunakan asersi dalam metode publik bahkan lebih penting, karena di sana Anda tidak mengontrol input dan mungkin lebih besar kemungkinan asumsi rusak.
Pengujian kondisi input harus dilakukan di semua metode publik dan yang dilindungi. Jika input diteruskan langsung ke metode pribadi, maka pengujian inputnya mungkin berlebihan.
Menguji kondisi keluaran (misalnya keadaan objek atau nilai pengembalian! = Null) harus dilakukan dalam metode dalam (mis. Metode pribadi). Jika output dilewatkan langsung dari metode pribadi ke output dari metode publik tanpa perhitungan tambahan atau perubahan keadaan dalam, maka pengujian kondisi output dari metode publik mungkin berlebihan.
Saya setuju dengan Oleksi, bagaimanapun, bahwa redundansi dapat meningkatkan keterbacaan dan juga dapat meningkatkan pemeliharaan (jika penugasan langsung atau pengembalian tidak lagi terjadi di masa depan).
sumber
Sulit untuk menjadi agnostik bahasa tentang masalah ini, karena rincian tentang bagaimana penegasan dan penanganan kesalahan / pengecualian yang tepat diterapkan memiliki pengaruh pada jawabannya. Inilah $ 0,02 saya, berdasarkan pengetahuan saya tentang Java & C ++.
Pernyataan dalam metode pribadi adalah hal yang baik, dengan asumsi Anda tidak berlebihan dan menempatkannya di mana - mana . Jika Anda menempatkan mereka pada metode yang sangat sederhana atau berulang kali memeriksa hal-hal seperti bidang yang tidak dapat diubah, maka Anda mengacaukan kodenya dengan sia-sia.
Pernyataan dalam metode publik umumnya sebaiknya dihindari. Anda masih harus melakukan hal-hal seperti memeriksa bahwa kontrak metode tidak dilanggar, tetapi jika demikian maka Anda harus melempar pengecualian yang diketik dengan pesan yang bermakna, mengembalikan keadaan jika memungkinkan, dll. (Apa yang @rwong sebut "penuh" penanganan penanganan kesalahan yang tepat ").
Secara umum, Anda hanya harus menggunakan pernyataan untuk membantu Anda pembangunan / debugging. Anda tidak dapat berasumsi bahwa siapa pun yang menggunakan API Anda bahkan akan memiliki pernyataan diaktifkan ketika mereka menggunakan kode Anda. Meskipun mereka memiliki beberapa kegunaan dalam membantu mendokumentasikan kode, sering kali ada cara yang lebih baik untuk mendokumentasikan hal-hal yang sama (yaitu dokumentasi metode, pengecualian).
sumber
Menambahkan ke daftar (kebanyakan) jawaban luar biasa, alasan lain untuk banyak menegaskan, dan duplikasi, adalah bahwa Anda tidak tahu bagaimana, kapan atau oleh siapa kelas akan dimodifikasi selama waktu hidup itu. Jika Anda menulis kode membuang yang akan mati dalam setahun, bukan masalah. Jika Anda menulis kode yang akan digunakan dalam 20 tahun ke depan, kode itu akan terlihat sangat berbeda - dan asumsi yang Anda buat mungkin tidak lagi valid. Orang yang melakukan perubahan itu akan berterima kasih atas pernyataannya.
Juga tidak semua programmer sempurna - sekali lagi, pernyataan itu berarti bahwa salah satu dari "slip up" itu tidak akan menyebar terlalu jauh.
Jangan meremehkan efek yang ditimbulkan oleh pernyataan ini (dan pemeriksaan lain tentang asumsi) dalam mengurangi biaya perawatan.
sumber
Memiliki duplikat pernyataan tidak salah, tetapi memiliki pernyataan "hanya untuk memastikan" bukan yang terbaik. Itu benar-benar bermuara pada apa yang sebenarnya setiap tes coba capai. Hanya menegaskan apa yang benar-benar dibutuhkan. Jika tes menggunakan Moq untuk memverifikasi metode dipanggil, tidak masalah apa yang terjadi setelah metode dipanggil, tes hanya berkaitan dengan memastikan metode dipanggil.
Jika setiap tes unit tunggal memiliki set penegasan yang sama, kecuali untuk satu atau dua, maka ketika Anda sedikit refactor semua tes bisa gagal karena alasan yang sama persis, daripada menunjukkan kepada Anda dampak sebenarnya dari refactor. Anda bisa berakhir dalam situasi di mana Anda menjalankan semua tes, semuanya gagal karena setiap tes memiliki menegaskan yang sama, Anda memperbaiki kegagalan itu, menjalankan tes lagi, mereka gagal karena alasan lain, Anda memperbaiki kegagalan itu. Ulangi sampai selesai.
Juga pertimbangkan pemeliharaan proyek pengujian Anda. Apa yang terjadi ketika Anda menambahkan parameter baru, atau outputnya sedikit diubah, apakah Anda harus kembali melalui banyak tes dan mengubah pernyataan atau menambahkan pernyataan? Dan, tergantung pada kode Anda, Anda akhirnya harus mengatur lebih banyak hanya untuk memastikan semua pernyataan lulus.
Saya dapat memahami daya tarik ingin memasukkan duplikat pernyataan dalam unit test, tetapi itu benar-benar berlebihan. Saya menempuh jalur yang sama dengan proyek pengujian pertama saya. Saya menjauh dari itu karena pemeliharaan sendiri membuat saya gila.
sumber
Jika kerangka kerja pengujian Anda memungkinkan pengakses, maka unit testing metode pribadi juga merupakan ide bagus (IMO).
Saya lakukan. Pernyataan tidak apa-apa, tetapi tujuan pertama Anda harus membuatnya sehingga skenario itu bahkan tidak mungkin ; bukan hanya itu tidak terjadi.
sumber
Ini latihan yang buruk.
Anda tidak boleh menguji metode publik / pribadi. Anda harus menguji kelas secara keseluruhan. Pastikan Anda memiliki cakupan yang baik.
Jika Anda menggunakan cara (primitif) untuk menguji setiap metode secara terpisah sebagai patokan, Anda akan merasa sangat sulit untuk memperbaiki kelas Anda di masa depan. Dan itulah salah satu hal terbaik yang dapat Anda lakukan TDD.
Selain itu, ini adalah duplikasi. Lebih jauh, itu menunjukkan bahwa penulis kode tidak benar-benar tahu apa yang dia lakukan. Dan lucunya, Anda lakukan .
Beberapa orang memperlakukan tes mereka dengan sedikit perhatian dibandingkan kode produksi mereka. Seharusnya tidak. Jika ada, pengalaman saya menyarankan untuk bahkan merawat tes dengan lebih hati-hati. Mereka layak.
sumber