Asumsikan kita memiliki aplikasi tingkat perusahaan besar tanpa tes unit / fungsional. Tidak ada proses pengembangan yang digerakkan oleh tes selama pengembangan karena tenggat waktu yang sangat ketat (saya tahu kita seharusnya tidak pernah menjanjikan tenggat waktu yang ketat ketika kita tidak yakin, tetapi apa yang dilakukan sudah dilakukan!)
Sekarang setelah semua tenggat waktu berlalu dan semuanya tenang, semua orang sepakat untuk mengubah kami menjadi tim berbasis TDD / BDD yang produktif ... Yay!
Sekarang pertanyaannya adalah tentang kode yang sudah kita miliki: (1) Apakah masih baik-baik saja atau ide yang bagus untuk menghentikan sebagian besar pengembangan dan mulai menulis seluruh kasus uji yang mungkin dari awal, meskipun semuanya bekerja sepenuhnya OKE (belum!) ? Atau (2) lebih baik menunggu sesuatu yang buruk terjadi dan kemudian selama perbaikan menulis tes unit baru, atau (3) bahkan melupakan kode sebelumnya dan hanya menulis tes unit untuk kode baru saja dan menunda semuanya ke refactor besar berikutnya.
Ada beberapa artikel bagus dan terkait seperti ini . Saya masih tidak yakin apakah layak untuk berinvestasi dalam hal ini mengingat kami memiliki waktu yang sangat terbatas dan banyak proyek / pekerjaan lain menunggu kami.
Catatan : Pertanyaan ini menjelaskan / membayangkan situasi yang benar-benar aneh di tim pengembangan. Ini bukan tentang saya atau rekan saya; itu hanya situasi imajiner. Anda mungkin berpikir ini seharusnya tidak pernah terjadi atau manajer pengembangan bertanggung jawab atas kekacauan seperti itu! Tapi bagaimanapun, apa yang dilakukan sudah selesai. Jika memungkinkan, tolong jangan downvote hanya karena Anda pikir ini seharusnya tidak pernah terjadi.
sumber
int
nilai dan mengembalikan sesuatu yang spesifik, tidak mungkin untuk menulis unit-test untuk setiapint
nilai yang mungkin , tetapi mungkin masuk akal untuk menguji beberapa nilai berguna yang mungkin menambah tiga kode, seperti angka negatif (termasukminint
), nolmaxint
,, dll. untuk memastikan bahwa beberapa kasus tepi tertutup.Jawaban:
Pernyataan ini sangat memprihatinkan. Bukan karena itu berarti Anda berkembang tanpa TDD atau karena Anda tidak menguji semuanya. Ini mengkhawatirkan, karena itu menunjukkan Anda berpikir TDD akan memperlambat Anda dan membuat Anda melewatkan tenggat waktu.
Selama Anda melihatnya dengan cara ini Anda tidak siap untuk TDD. TDD bukanlah sesuatu yang bisa Anda lakukan secara bertahap. Anda tahu cara melakukannya atau tidak. Jika Anda mencoba melakukannya di tengah jalan, Anda akan berhasil dan diri Anda terlihat buruk.
TDD adalah sesuatu yang harus Anda praktikkan di rumah terlebih dahulu. Belajarlah untuk melakukannya, karena ini membantu Anda membuat kode sekarang . Bukan karena seseorang menyuruhmu melakukannya. Bukan karena itu akan membantu ketika Anda melakukan perubahan nanti. Ketika itu menjadi sesuatu yang Anda lakukan karena Anda sedang terburu-buru maka Anda siap melakukannya secara profesional.
TDD adalah sesuatu yang dapat Anda lakukan di toko mana pun . Anda bahkan tidak perlu menyerahkan kode tes Anda. Anda dapat menyimpannya sendiri jika yang lain meremehkan tes. Ketika Anda melakukannya dengan benar, tes mempercepat pengembangan Anda, bahkan jika tidak ada orang lain yang menjalankannya.
Di sisi lain jika orang lain menyukai dan menjalankan tes Anda, Anda harus tetap ingat bahwa bahkan di toko TDD itu bukan tugas Anda untuk memeriksa tes. Ini untuk membuat kode produksi yang terbukti bekerja. Jika kebetulan bisa diuji, rapi.
Jika Anda berpikir manajemen harus percaya pada TDD atau bahwa sesama pembuat kode Anda harus mendukung tes Anda, maka Anda mengabaikan hal terbaik yang dilakukan TDD untuk Anda. Dengan cepat menunjukkan kepada Anda perbedaan antara apa yang Anda pikir kode Anda lakukan dan apa yang sebenarnya dilakukannya.
Jika Anda tidak dapat melihat bagaimana itu sendiri dapat membantu Anda memenuhi tenggat waktu lebih cepat maka Anda tidak siap untuk TDD di tempat kerja. Anda perlu berlatih di rumah.
Yang mengatakan, itu bagus ketika tim dapat menggunakan tes Anda untuk membantu mereka membaca kode produksi Anda dan ketika manajemen akan membeli alat TDD baru yang rumit.
Terlepas dari apa yang dilakukan tim, tidak selalu merupakan ide yang baik untuk menulis semua kasus uji yang mungkin. Tulis kasus uji yang paling berguna. Cakupan kode 100% dikenakan biaya. Jangan abaikan hukum pengembalian yang semakin berkurang hanya karena menghakimi itu sulit.
Hemat energi pengujian Anda untuk logika bisnis yang menarik. Hal-hal yang membuat keputusan dan menegakkan kebijakan. Uji coba itu. Membosankan jelas kode lem struktural yang mudah dibaca yang hanya kabel barang bersama-sama tidak perlu pengujian hampir sama buruknya.
Ini adalah pemikiran "mari kita lakukan penulisan ulang lengkap". Ini menghancurkan pengetahuan yang sulit dimenangkan. Jangan meminta manajemen waktu untuk menulis tes. Cukup tulis tes. Setelah Anda tahu apa yang Anda lakukan, tes tidak akan memperlambat Anda.
Saya akan menjawab 2 dan 3 dengan cara yang sama. Ketika Anda mengubah kode, untuk alasan apa pun, akan sangat bagus jika Anda bisa mengikuti tes. Jika kode ini lawas, saat ini tidak dapat menerima tes. Yang berarti sulit untuk mengujinya sebelum mengubahnya. Nah, karena Anda tetap mengubahnya, Anda dapat mengubahnya menjadi sesuatu yang dapat diuji dan mengujinya.
Itu opsi nuklir. Berisiko. Anda membuat perubahan tanpa tes. Ada beberapa trik kreatif untuk menguji kode lama sebelum Anda mengubahnya. Anda mencari apa yang disebut jahitan yang memungkinkan Anda mengubah perilaku kode Anda tanpa mengubah kode. Anda mengubah file konfigurasi, membuat file, apa pun yang diperlukan.
Michael Feathers memberi kami sebuah buku tentang ini: Bekerja Efektif dengan Legacy Code . Coba baca, dan Anda akan melihat bahwa Anda tidak perlu membakar semua yang lama untuk membuat sesuatu yang baru.
sumber
Diberi kode lawas 1 , tulis unit test dalam situasi berikut:
Berguna sebagai unit test adalah, menciptakan lengkap tes unit suite untuk yang ada 1 basis kode mungkin bukan ide yang realistis. Kekuatan yang telah mendorong Anda untuk memenuhi tenggat waktu yang ketat. Mereka tidak memberi Anda waktu untuk membuat unit test yang memadai saat Anda berkembang. Apakah Anda pikir mereka akan memberi Anda waktu yang cukup untuk membuat tes untuk "program yang berfungsi"?
1 Kode lama adalah kode tanpa tes unit. Ini adalah definisi kode warisan TDD. Itu berlaku bahkan jika kode warisan baru dikirim [bahkan jika tinta belum kering].
sumber
Dalam pengalaman saya, tes tidak perlu cakupan total untuk membantu. Alih-alih, Anda mulai menuai berbagai jenis manfaat saat cakupan meningkat:
Yang benar adalah, jika Anda tidak memulai dengan BDD Anda tidak akan pernah sampai di sana, karena pekerjaan yang diperlukan untuk menguji setelah pengkodean hanya berlebihan. Masalahnya bukan menulis tes, tetapi lebih menyadari persyaratan aktual (daripada detail implementasi insidental) dan mampu merancang perangkat lunak dengan cara yang fungsional dan mudah untuk diuji. Saat Anda menulis tes pertama atau bersama-sama dengan kode, ini praktis gratis.
Karena fitur baru memerlukan pengujian, tetapi pengujian memerlukan perubahan desain, tetapi refactoring juga memerlukan pengujian, Anda memiliki sedikit masalah ayam dan telur. Ketika perangkat lunak Anda merayap mendekati cakupan yang layak, Anda harus melakukan beberapa refactoring dengan hati-hati pada bagian-bagian kode tempat fitur baru muncul, hanya untuk membuat fitur baru dapat diuji. Ini akan banyak memperlambat Anda - awalnya. Tetapi dengan hanya melakukan refactoring dan menguji bagian-bagian di mana pengembangan baru diperlukan, tes juga fokus pada area di mana mereka paling dibutuhkan. Kode yang stabil dapat dilanjutkan tanpa tes: jika buggy, Anda harus mengubahnya.
Saat Anda mencoba beradaptasi dengan TDD, metrik yang lebih baik daripada cakupan total proyek akan menjadi cakupan uji di bagian yang sedang diubah. Cakupan ini harus sangat tinggi sejak awal, meskipun tidak layak untuk menguji semua bagian kode yang terkena dampak refactoring. Juga, Anda menuai sebagian besar manfaat dari cakupan uji tinggi dalam komponen yang diuji. Itu tidak sempurna, tetapi masih cukup bagus.
Perhatikan bahwa meskipun tes unit tampaknya umum, dimulai dengan bagian terkecil bukanlah strategi yang cocok untuk mendapatkan perangkat lunak warisan yang sedang diuji. Anda akan ingin memulai dengan tes integrasi yang menjalankan sebagian besar perangkat lunak sekaligus.
Misalnya saya merasa berguna untuk mengekstrak kasus uji integrasi dari file log dunia nyata. Tentu saja menjalankan tes semacam itu bisa memakan banyak waktu, itulah sebabnya Anda mungkin ingin mengatur server otomatis yang menjalankan tes secara teratur (misalnya server Jenkins yang dipicu oleh komitmen). Biaya pengaturan dan pemeliharaan server seperti itu sangat kecil dibandingkan dengan tidak menjalankan tes secara teratur, dengan ketentuan bahwa setiap kegagalan tes benar-benar diperbaiki dengan cepat.
sumber
Jangan menulis tes untuk kode yang ada. Itu tidak layak.
Apa yang Anda buat sudah agak diuji dengan cara yang benar-benar informal - Anda mencobanya dengan tangan terus-menerus, orang-orang melakukan beberapa pengujian yang tidak diautomasi, sedang digunakan sekarang. Itu berarti Anda tidak akan menemukan banyak bug .
Yang tersisa adalah bug yang tidak Anda pikirkan. Tapi itu persis yang Anda tidak akan berpikir untuk menulis unit test untuk keduanya, jadi Anda mungkin masih tidak akan menemukannya.
Juga, alasan untuk TDD adalah membuat Anda berpikir tentang apa persyaratan sebenarnya dari sedikit kode sebelum menulisnya. Dengan cara apa pun yang berbeda, Anda sudah melakukannya.
Sementara itu, masih banyak pekerjaan untuk menulis tes ini seperti menulisnya sebelumnya. Akan memakan banyak waktu, untuk sedikit manfaat.
Dan sangat membosankan untuk menulis banyak tes tanpa ada kode di antaranya dan hampir tidak menemukan bug. Jika Anda mulai melakukan ini, orang yang baru mengenal TDD akan membencinya .
Singkatnya, devs akan membencinya dan manajer akan melihatnya mahal, sementara tidak banyak bug ditemukan. Anda tidak akan pernah sampai ke bagian TDD yang sebenarnya.
Gunakan pada hal-hal yang ingin Anda ubah, sebagai bagian normal dari proses.
sumber
Tes adalah sarana untuk mengkomunikasikan pemahaman.
Karena itu hanya tulis tes untuk apa yang Anda pahami harus benar.
Anda hanya bisa memahami apa yang seharusnya benar ketika Anda bekerja dengannya.
Karena itu hanya tulis tes untuk kode yang Anda kerjakan.
Ketika Anda bekerja dengan kode Anda akan belajar.
Karena itu tulis dan tulis ulang tes untuk menangkap apa yang telah Anda pelajari.
Bilas dan ulangi.
Biarkan alat cakupan kode dijalankan dengan tes Anda, dan hanya menerima komitmen ke jalur utama yang tidak mengurangi cakupan. Akhirnya Anda akan mencapai tingkat cakupan yang tinggi.
Jika Anda belum bekerja dengan kode tersebut untuk sementara waktu, keputusan bisnis perlu dibuat. Sekarang sangat mungkin warisan sehingga tidak ada seorang pun di tim Anda yang tahu cara bekerja dengannya. Mungkin memiliki perpustakaan / kompiler / dokumentasi yang sudah ketinggalan zaman yang merupakan tanggung jawab besar dalam segala hal.
Dua pilihan:
sumber
Salah satu tujuan utama tes adalah untuk memastikan bahwa perubahan tidak merusak apa pun. Ini adalah proses tiga langkah:
Ini berarti bahwa Anda perlu melakukan tes sebelum Anda benar-benar mengubah sesuatu. Jika Anda memilih jalur kedua, itu artinya Anda harus memaksa pengembang Anda untuk menulis tes bahkan sebelum mereka menyentuh kode. Dan saya sangat curiga bahwa ketika sudah dihadapkan dengan perubahan dunia nyata, para pengembang tidak akan memberikan unit tes perhatian yang layak mereka dapatkan.
Jadi saya menyarankan untuk membagi tugas penulisan tes dan perubahan untuk menghindari pengembang mengorbankan kualitas satu untuk yang lain.
Hanya untuk menunjukkan ini secara khusus, itu adalah kesalahpahaman umum bahwa Anda hanya perlu tes ketika kode tidak berfungsi. Anda memerlukan tes saat kode berfungsi juga, misalnya untuk membuktikan kepada seseorang bahwa [bug yang baru muncul] bukan karena bagian Anda karena tes masih berjalan.
Mengonfirmasi bahwa semuanya masih berfungsi seperti sebelumnya adalah manfaat penting dari pengujian yang Anda abaikan saat Anda menyiratkan bahwa Anda tidak memerlukan pengujian saat kode berfungsi.
Idealnya, semua kode sumber yang ada sekarang harus mendapatkan tes unit. Namun, ada argumen yang masuk akal bahwa waktu dan upaya (dan biaya) yang diperlukan untuk melakukannya sama sekali tidak relevan untuk proyek-proyek tertentu.
Misalnya, aplikasi yang tidak lagi dikembangkan dan tidak diharapkan untuk diubah lagi (mis. Klien tidak lagi menggunakannya, atau klien bukan lagi klien), Anda dapat berargumen bahwa tidak relevan untuk menguji kode ini lagi .
Namun, itu tidak jelas memotong di mana Anda menarik garis. Ini adalah sesuatu yang perlu dilihat perusahaan dalam analisis manfaat biaya. Tes menulis membutuhkan waktu dan tenaga, tetapi apakah mereka mengharapkan pengembangan di masa depan pada aplikasi itu? Apakah keuntungan dari memiliki unit test lebih besar daripada biaya penulisan mereka?
Ini bukan keputusan yang dapat Anda (sebagai pengembang) buat. Paling-paling, Anda dapat menawarkan perkiraan waktu yang dibutuhkan untuk melaksanakan tes pada proyek tertentu, dan terserah manajemen untuk memutuskan apakah ada harapan yang cukup untuk benar-benar perlu mempertahankan / mengembangkan proyek.
Jika refactor utama berikutnya diberikan, maka Anda memang perlu menulis tes.
Tetapi jangan menundanya sampai Anda dihadapkan dengan perubahan besar. Poin awal saya (tidak menggabungkan penulisan tes dan memperbarui kode) masih ada, tapi saya ingin menambahkan poin kedua di sini: pengembang Anda saat ini mengetahui jalannya proyek lebih baik daripada dalam enam bulan jika mereka menghabiskan waktu bekerja pada proyek lain. Memanfaatkan periode waktu di mana para pengembang sudah melakukan pemanasan dan tidak perlu memikirkan bagaimana hal-hal bekerja lagi di masa depan.
sumber
Dua sen saya:
Tunggu hingga peningkatan teknis utama ke sistem dan tulis tesnya lalu ... secara resmi dengan dukungan bisnis.
Atau, katakanlah Anda adalah toko SCRUM, beban kerja Anda diwakili oleh kapasitas dan Anda dapat mengalokasikan% dari itu untuk pengujian unit, tetapi ...
Mengatakan Anda akan kembali dan menulis tes itu naif, apa yang sebenarnya akan Anda lakukan adalah menulis tes, refactor, dan menulis lebih banyak tes setelah refactor membuat kode lebih dapat diuji, itulah sebabnya yang terbaik untuk memulai dengan tes seperti yang Anda sudah ketahui, dan ...
Yang terbaik bagi penulis asli untuk menulis tes dan refactor kode yang mereka tulis sebelumnya, itu tidak ideal, tetapi dari pengalaman Anda ingin refactor membuat kode lebih baik tidak lebih buruk.
sumber