Salah satu dari beberapa hal yang disetujui sebagian besar pengembang perangkat lunak adalah Anda tidak harus bergantung pada kode untuk bekerja dengan benar kecuali Anda mengujinya. Jika Anda tidak mengujinya, mungkin ada bug tersembunyi yang hanya akan menyebabkan Anda bekerja lebih keras.
Saya mengerti bagaimana menguji kode normal saya, tetapi bagaimana saya harus menguji kode pengujian saya untuk memastikannya dapat secara efektif menemukan dan melaporkan kesalahan ketika mereka ada? Saya pribadi sudah cukup bodoh untuk menulis kasus-kasus ujian yang keliru yang seharusnya lulus ketika seharusnya tidak, sehingga mengalahkan tujuan dari tes penulisan saya di tempat pertama. Untungnya, saya menemukan dan memperbaiki kesalahan dalam waktu, tetapi menurut mantra pengujian sepertinya tidak ada rangkaian tes yang akan lengkap tanpa memiliki serangkaian tes sendiri untuk memastikan itu berfungsi.
Bagi saya, cara terbaik untuk melakukan ini adalah dengan memastikan tes gagal untuk kode buggy. * Jika saya menghabiskan 2 menit secara bergantian menambahkan bug ke kode dan memastikan gagal, saya harus memiliki tingkat kepercayaan yang dapat diterima bahwa tes 'berhasil'. Ini membawa saya ke pertanyaan kedua: Apa cara yang baik untuk memperkenalkan bug untuk memastikan bahwa mereka tertangkap oleh kasus uji? Jika saya hanya mengomentari pernyataan secara acak, pastikan cabang yang salah if-else
dijalankan dengan meniadakan kondisinya, dan mengubah urutan eksekusi kode dengan efek samping, dll., Sampai saya puas tes saya akan menangkap sebagian besarbug umum? Bagaimana pengembang profesional memvalidasi bahwa tes mereka benar-benar melakukan apa yang seharusnya mereka lakukan? Apakah mereka hanya menganggap tes itu berhasil, atau apakah mereka meluangkan waktu untuk mengujinya juga? Jika demikian, bagaimana mereka menguji tes?
Saya tidak menyarankan orang-orang harus menghabiskan begitu banyak waktu untuk menguji tes mereka dan kemudian menguji tes untuk tes mereka sehingga mereka tidak pernah benar-benar menulis kode asli, tetapi saya telah melakukan hal-hal yang cukup bodoh yang saya rasa saya bisa mendapat manfaat dari sedikit dari 'pengujian meta', dan ingin tahu tentang cara terbaik untuk melakukannya. : D
* Saya dapat memeriksa untuk melihat apakah tes lulus ketika menguji kode 'bebas bug', tetapi menggunakan kode sebagai spek untuk pengujian tampaknya cukup terbelakang ...
sumber
Jawaban:
Alur standar untuk TDD adalah:
Tes untuk tes Anda dalam hal ini adalah langkah 1 - memastikan bahwa tes gagal sebelum Anda membuat perubahan kode.
Tes lain yang saya suka adalah apakah Anda dapat menghapus beberapa kode dan mengimplementasikannya kembali dengan cara yang berbeda, dan pengujian Anda gagal setelah penghapusan tetapi bekerja dengan algoritma yang berbeda di tempat.
Seperti halnya semua hal, tidak ada peluru ajaib. Lupa menulis tes yang diperlukan sama mudahnya bagi pengembang untuk melakukan seperti lupa menulis kode. Setidaknya jika Anda melakukan keduanya, Anda memiliki peluang dua kali lebih banyak untuk menemukan kelalaian Anda.
sumber
null
dan gagal pada langkah 1. Anda membuat perubahan kode terkecil yang membuatnya lulus dengan mengembalikan daftar kosong. Tes sekarang "hijau" karena Anda memiliki dua bug.null
dan bukan untuk kosong.)Salah satu pendekatan adalah Mutation Testing , menggunakan alat seperti Jester :
sumber
Tes untuk tes? Jangan melewati jalan itu. Maka Anda mungkin perlu tes untuk tes untuk tes, dan kemudian tes untuk tes untuk tes untuk ... di mana Anda berhenti?
Alur pengujian biasa berjalan seperti ini, dan sebagai pengembang, Anda akan menghabiskan sebagian besar waktu Anda pada poin 1-3:
Kode Anda pada akhirnya akan "menumbuhkan" bug-nya sendiri, jangan buang waktu memperkenalkannya dengan tangan. Belum lagi, apakah hal yang Anda tahu tentang dimuka benar-benar bug? Bug akan datang, saya tidak akan khawatir tentang itu.
Ini sebenarnya merupakan pendekatan yang layak untuk memverifikasi apakah Anda benar-benar menguji apa yang Anda pikir Anda lakukan. Saya tidak berpikir itu selalu baik karena menderita masalah yang sama seperti "test for test for test ..." hal: kapan Anda berhenti mengubah kode mengetahui kode yang Anda uji 100% berfungsi?
Ini juga baik untuk diingat tentang semua saran programmer pragmatis klasik waktu - Anda tidak akan membutuhkannya . Jadilah gesit, tulis tes dan kode untuk bug yang sebenarnya, sebagai gantinya untuk hipotesis yang mungkin atau mungkin tidak muncul.
sumber
Dengan konstruksi, kode fungsional dan kode uji diuji satu terhadap yang lain. Satu masalah tetap ada: kasus bug mode umum, ketika bug dalam kode fungsional disembunyikan oleh bug dalam kode uji. TDD tidak kebal terhadap efek ini. Inilah sebabnya mengapa pengujian biasanya dilakukan pada beberapa tingkatan oleh orang yang berbeda untuk mengurangi kemungkinan ini.
sumber
Anda menguji unit test Anda satu kali saat Anda menulisnya, di debugger. Kemudian Anda membiarkannya dan melupakannya. Tidak ada masalah di sini.
Pertimbangkan ini. Apa tujuan dari tes unit? Ini memberi tahu Anda ketika salah satu dari banyak perubahan yang akan Anda buat di program utama Anda secara tidak sengaja mengubah logika dalam program itu. Anda ingin memilikinya karena Anda tahu bahwa perubahan apa pun berpotensi merusak sesuatu. Itulah sebabnya tidak ada masalah jika Anda tidak menguji tes Anda: Anda tidak mengacaukan tes Anda sampai Anda dengan sengaja mengubah logika program Anda (yang akan mengharuskan Anda untuk meninjau kembali tes dan mengujinya sekali lagi), jadi Anda Tes tidak mungkin pecah secara tidak sengaja.
sumber
Ada pengujian mutasi yang mengevaluasi dan mengukur kesesuaian dan kualitas pengujian.
Kita dapat menggunakan ini untuk mengevaluasi "tes" itu sendiri.
Secara singkat, Kami dapat mengevaluasi pengujian kami (mis. TestA) dengan menguji TestA dapat menemukan perbedaan antara kode dan kode mutasinya (sangat mirip tetapi kode sedikit berbeda dengan kode asli).
Jika TestA tidak dapat menemukan perbedaan antara kode dan kode mutasinya, itu berarti bahwa TestA memiliki peraturan terlalu kasar untuk menguji kode asli.
sumber