Saya adalah pengembang solo dengan lingkungan kerja yang terbatas waktu di mana waktu pengembangan biasanya berkisar 1-4 minggu per proyek, tergantung pada persyaratan, urgensi, atau keduanya. Pada waktu tertentu saya menangani sekitar 3-4 proyek, beberapa memiliki jadwal yang tumpang tindih satu sama lain.
Diharapkan, kualitas kode menderita. Saya juga tidak memiliki pengujian formal; biasanya turun untuk berjalan melalui sistem sampai agak rusak. Akibatnya, sejumlah besar bug lolos ke produksi, yang harus saya perbaiki dan pada gilirannya mengembalikan proyek saya yang lain.
Di sinilah unit testing masuk. Ketika dilakukan dengan benar, itu harus menjaga bug, apalagi yang melarikan diri ke produksi, seminimal mungkin. Di sisi lain, tes menulis dapat mengambil banyak waktu, yang tidak terdengar baik dengan proyek yang dibatasi waktu seperti tambang.
Pertanyaannya adalah, seberapa jauh perbedaan waktu akan menulis kode yang diuji unit daripada kode yang belum diuji, dan bagaimana skala perbedaan waktu itu sebagai lingkup proyek bertambah?
sumber
Jawaban:
Semakin Anda menguji, semakin banyak biayanya untuk menulis tes.
Semakin lama bug hidup, semakin mahal untuk memperbaikinya.
Hukum pengembalian yang semakin berkurang memastikan Anda dapat menguji diri Anda sendiri untuk mencoba memastikan tidak ada bug.
Buddha mengajarkan kebijaksanaan jalan tengah. Tesnya bagus. Ada hal yang terlalu baik. Kuncinya adalah mengetahui kapan Anda tidak seimbang.
Setiap baris kode yang Anda tulis tanpa tes akan memiliki biaya yang jauh lebih besar untuk menambahkan tes lebih lambat daripada jika Anda telah menulis tes sebelum menulis kode.
Setiap baris kode tanpa tes akan secara signifikan lebih sulit untuk di-debug atau ditulis ulang.
Setiap tes yang Anda tulis akan memakan waktu.
Setiap bug akan membutuhkan waktu untuk memperbaikinya.
Orang beriman akan memberitahu Anda untuk tidak menulis satu baris kode tanpa terlebih dahulu menulis tes gagal. Tes memastikan Anda mendapatkan perilaku yang Anda harapkan. Ini memungkinkan Anda untuk mengubah kode dengan cepat tanpa khawatir akan memengaruhi sisa sistem karena tes membuktikan perilaku yang sama.
Anda harus menimbang semua itu terhadap fakta bahwa tes tidak menambah fitur. Kode produksi menambah fitur. Dan fitur adalah apa yang membayar tagihan.
Secara pragmatis, saya menambahkan semua tes yang bisa saya lakukan. Saya mengabaikan komentar demi menonton tes. Saya bahkan tidak memercayai kode untuk melakukan apa yang saya pikirkan. Saya percaya tes. Tapi aku dikenal sering melempar hujan es dan beruntung.
Namun, banyak coders yang sukses tidak melakukan TDD. Itu tidak berarti mereka tidak menguji. Mereka hanya tidak secara obyektif bersikeras bahwa setiap baris kode memiliki tes otomatis yang menentangnya. Bahkan Paman Bob mengakui dia tidak menguji UI-nya. Dia juga menegaskan Anda memindahkan semua logika dari UI.
Sebagai metafora sepakbola (itulah sepak bola Amerika) TDD adalah permainan darat yang bagus. Manual hanya menguji di mana Anda menulis setumpuk kode dan berharap itu berfungsi adalah permainan yang lewat. Anda bisa pandai keduanya. Karier Anda tidak akan mencapai babak playoff kecuali Anda dapat melakukan keduanya. Itu tidak akan membuat superbowl sampai Anda belajar kapan harus memilih masing-masing. Tetapi jika Anda membutuhkan dorongan ke arah tertentu: panggilan pejabat melawan saya lebih sering ketika saya lewat.
Jika Anda ingin mencoba TDD, saya sangat menyarankan Anda berlatih sebelum mencoba melakukannya di tempat kerja. TDD dilakukan setengah jalan, setengah hati, dan setengah assed adalah alasan besar beberapa orang tidak menghormatinya. Ini seperti menuangkan satu gelas air ke gelas lainnya. Jika Anda tidak berkomitmen dan melakukannya dengan cepat dan sepenuhnya, Anda berakhir menggiring air ke seluruh meja.
sumber
Saya setuju dengan sisa jawaban tetapi untuk menjawab pertanyaan perbedaan waktu secara langsung.
Roy Osherove dalam bukunya The Art of Unit Testing, Edisi Kedua halaman 200 melakukan studi kasus tentang implementasi proyek berukuran sama dengan tim yang sama (keahlian) untuk dua klien yang berbeda di mana satu tim melakukan pengujian sedangkan yang lainnya tidak.
Hasilnya seperti:
Jadi pada akhir proyek Anda mendapatkan lebih sedikit waktu dan bug lebih sedikit. Ini tentu saja tergantung pada seberapa besar proyek itu.
sumber
Hanya ada satu studi yang saya ketahui yang mempelajari ini dalam "pengaturan dunia nyata": Menyadari peningkatan kualitas melalui pengembangan yang digerakkan oleh tes: hasil dan pengalaman dari empat tim industri . Mahal untuk melakukan ini dengan cara yang masuk akal, karena pada dasarnya berarti Anda perlu mengembangkan perangkat lunak yang sama dua kali (atau idealnya bahkan lebih sering) dengan tim yang sama, dan kemudian membuang semua kecuali satu.
Hasil penelitian adalah peningkatan waktu pengembangan antara 15% -35% (yang jauh dari angka 2x yang sering dikutip oleh kritik TDD) dan penurunan kepadatan cacat pra-rilis dari 40% -90% (! ). Perhatikan bahwa semua tim tidak memiliki pengalaman sebelumnya dengan TDD, sehingga orang dapat berasumsi bahwa peningkatan waktu setidaknya dapat sebagian dikaitkan dengan pembelajaran, dan dengan demikian akan turun lebih jauh dari waktu ke waktu, tetapi ini tidak dinilai oleh penelitian.
Perhatikan bahwa penelitian ini adalah tentang TDD, dan pertanyaan Anda adalah tentang pengujian unit, yang merupakan hal yang sangat berbeda, tetapi ini adalah yang terdekat yang bisa saya temukan.
sumber
null
, fungsional atas imperatif, kontrak kode, analisis statis, refactoring otomatis, tidak ada wadah IOC (tapi DI) dll. Saya bertaruh nilai itu unit test akan menurun (tetapi tidak hilang).Selesai, pengembangan dengan unit test bisa lebih cepat bahkan tanpa mempertimbangkan manfaat bug tambahan yang ditangkap.
Faktanya adalah, saya bukan pembuat kode yang cukup baik untuk hanya memiliki kode saya bekerja segera setelah dikompilasi. Ketika saya menulis / memodifikasi kode, saya harus menjalankan kode untuk memastikan itu melakukan apa yang saya pikirkan. Pada satu proyek, ini cenderung berakhir seperti:
Dan tentu saja, setelah semua itu, biasanya perlu beberapa perjalanan bolak-balik untuk benar-benar melakukannya.
Sekarang, bagaimana jika saya menggunakan tes unit? Maka prosesnya lebih seperti:
Ini lebih mudah dan lebih cepat daripada menguji aplikasi secara manual. Saya masih harus menjalankan aplikasi secara manual (jadi saya tidak terlihat konyol ketika saya menyerahkan pekerjaan yang sebenarnya tidak berfungsi sama sekali), tetapi sebagian besar saya sudah menyelesaikan kekusutan, dan saya hanya memverifikasi pada titik itu. Sebenarnya saya biasanya membuat loop ini lebih ketat dengan menggunakan program yang secara otomatis mengulang tes saya ketika saya simpan.
Namun, ini tergantung pada bekerja di basis kode ramah-tes. Banyak proyek, bahkan yang memiliki banyak tes, membuat tes menulis sulit. Tetapi jika Anda berhasil, Anda dapat memiliki basis kode yang lebih mudah untuk diuji melalui tes otomatis daripada dengan pengujian manual. Sebagai bonus, Anda dapat menyimpan tes otomatis di sekitar, dan terus menjalankannya untuk mencegah regresi.
sumber
Meskipun sudah ada banyak jawaban, mereka agak berulang dan saya ingin mengambil cara yang berbeda. Tes unit berharga, jika dan hanya jika , mereka meningkatkan nilai bisnis . Pengujian demi pengujian (uji sepele atau tautologis), atau untuk mencapai beberapa metrik sewenang-wenang (seperti cakupan kode), adalah pemrograman kultus kargo.
Tes mahal, tidak hanya dalam waktu yang dibutuhkan untuk menulisnya, tetapi juga pemeliharaan. Mereka harus tetap sinkron dengan kode yang mereka uji atau mereka tidak berharga. Belum lagi biaya waktu menjalankannya pada setiap perubahan. Itu bukan pemecah kesepakatan (atau alasan untuk tidak melakukan yang benar-benar diperlukan), tetapi perlu diperhitungkan dalam analisis biaya-manfaat.
Jadi pertanyaan yang diajukan ketika memutuskan apakah atau tidak (atau jenis apa) untuk menguji suatu fungsi / metode, tanyakan pada diri sendiri 'apa nilai pengguna akhir yang saya buat / lindungi dengan tes ini?'. Jika Anda tidak dapat menjawab pertanyaan itu, di atas kepala Anda , maka ujian itu kemungkinan tidak sebanding dengan biaya penulisan / pemeliharaan. (atau Anda tidak memahami domain masalah, yang merupakan masalah waaaay lebih besar daripada kurangnya tes).
http://rbcs-us.com/documents/Why-Most-Unit-Testing-is-Waste.pdf
sumber
Itu tergantung pada orangnya, serta kompleksitas dan bentuk kode yang Anda kerjakan.
Bagi saya, pada sebagian besar proyek, menulis unit test berarti saya menyelesaikan pekerjaan sekitar 25% lebih cepat. Ya, bahkan termasuk waktu untuk menulis tes.
Karena faktanya adalah bahwa perangkat lunak tidak dilakukan ketika Anda menulis kode. Ini dilakukan ketika Anda mengirimkannya ke pelanggan dan mereka senang dengan itu. Sejauh ini, tes unit adalah cara paling efisien yang saya tahu untuk menangkap sebagian besar bug, mengisolasi sebagian besar bug untuk debugging, dan untuk mendapatkan kepercayaan bahwa kode itu baik. Anda harus melakukan hal-hal lagian , sehingga melakukannya dengan baik.
sumber
Masalahnya semakin buruk dengan bertambahnya usia proyek: karena setiap kali Anda menambahkan fungsionalitas baru dan / atau setiap kali Anda refactor implementasi yang ada, Anda harus menguji ulang apa yang sebelumnya diuji untuk memastikan bahwa itu masih berfungsi. Jadi, untuk proyek jangka panjang (multi-tahun), Anda mungkin perlu tidak hanya menguji fungsionalitas tetapi menguji kembali 100 kali dan lebih banyak lagi. Untuk alasan ini Anda mungkin mendapat manfaat dari memiliki tes otomatis . Namun, IMO cukup baik (atau bahkan, lebih baik) jika ini adalah tes sistem otomatis, daripada tes unit otomatis.
Masalah kedua adalah bahwa bug bisa lebih sulit ditemukan dan diperbaiki jika mereka tidak ditangkap lebih awal. Sebagai contoh jika ada bug dalam sistem dan saya tahu itu berfungsi dengan baik sebelum Anda membuat perubahan terbaru, maka saya akan memusatkan perhatian saya pada perubahan terbaru Anda untuk melihat bagaimana bug itu diperkenalkan. Tetapi jika saya tidak tahu bahwa sistem itu berfungsi sebelum Anda membuat perubahan terbaru Anda (karena sistem tidak diuji dengan benar sebelum perubahan terbaru Anda), maka bug bisa ada di mana saja.
Hal di atas berlaku terutama untuk kode yang dalam, dan lebih sedikit untuk kode yang dangkal misalnya menambahkan halaman web baru di mana halaman baru tidak akan mempengaruhi halaman yang ada.
Menurut pengalaman saya, itu tidak bisa diterima, jadi Anda mengajukan pertanyaan yang salah. Daripada bertanya apakah tes akan membuat pengembangan lebih cepat, Anda harus bertanya apa yang membuat pengembangan lebih bebas bug.
Pertanyaan yang lebih baik mungkin:
Belajar adalah proses dua tahap: belajar melakukannya dengan cukup baik, kemudian belajar melakukannya dengan lebih cepat.
sumber
Beberapa aspek untuk dipertimbangkan, tidak disebutkan dalam jawaban lainnya.
Ringkasan
Ketika memulai dengan tdd sulit untuk mencapai keadaan "lebih banyak manfaat daripada biaya" selama Anda berada di bawah "lingkungan kerja terbatas waktu" terutama jika ada "manajer pintar" yang memberi tahu Anda untuk "menyingkirkan yang mahal, tidak berguna menguji barang "
Catatan: dengan "unit testing" maksud saya "menguji modul dalam isolasi".
Catatan: dengan "pengujian regresi" yang saya maksud
sumber
Programmer, seperti orang yang menangani sebagian besar tugas, meremehkan berapa lama sebenarnya untuk menyelesaikannya. Dengan mengingat hal itu, menghabiskan 10 menit untuk menulis tes dapat dilihat sebagai waktu seseorang dapat menghabiskan menulis banyak kode ketika pada kenyataannya, Anda akan menghabiskan waktu itu datang dengan nama fungsi dan parameter yang sama yang Anda lakukan selama tes . Ini adalah skenario TDD.
Tidak menulis tes, sangat mirip memiliki kartu kredit; kita cenderung menghabiskan lebih banyak atau menulis lebih banyak kode. Lebih banyak kode memiliki lebih banyak bug.
Alih-alih memutuskan untuk memiliki cakupan kode total atau tidak sama sekali, saya sarankan berfokus pada bagian kritis dan rumit aplikasi Anda dan melakukan tes di sana. Dalam aplikasi perbankan, itu mungkin perhitungan bunga. Alat diagnostik mesin mungkin memiliki protokol kalibrasi yang kompleks. Jika Anda telah mengerjakan suatu proyek, Anda mungkin tahu apa itu dan di mana bug itu berada.
Mulai dengan lambat. Bangun kelancaran sebelum Anda menilai. Kamu selalu bisa berhenti.
sumber
Ada sejarah panjang dewan Programmer yang mempromosikan TDD dan metodologi pengujian lainnya, saya tidak akan mengingat argumen mereka dan setuju dengan mereka, tetapi di sini ada beberapa hal tambahan yang perlu dipertimbangkan yang seharusnya sedikit bernuansa:
Saya akan mengatakan pengujian itu baik, tetapi pastikan Anda menguji lebih awal dan menguji di mana keuntungannya.
sumber
mainTest()
yang memanggil semua modul pengujian Anda tidak terlalu sulit.Manfaat TDD yang sering diabaikan adalah bahwa tes bertindak sebagai perlindungan untuk memastikan Anda tidak memperkenalkan bug baru ketika Anda membuat perubahan.
Pendekatan TDD tidak diragukan lagi lebih banyak memakan waktu pada awalnya tetapi titik takeaway adalah Anda akan menulis lebih sedikit kode yang berarti lebih sedikit hal yang salah. Semua lonceng dan peluit yang sering Anda sertakan tidak akan berhasil masuk ke basis kode.
Ada adegan di film Swordfish di mana jika ingatanku, seorang hacker harus bekerja dengan pistol di kepalanya dan menjadi erm ... jika tidak terganggu. Intinya adalah itu jauh lebih mudah untuk bekerja ketika headspace Anda ada dalam kode dan Anda punya waktu di sisi Anda daripada berbulan-bulan dengan pelanggan berteriak pada Anda dan prioritas lainnya diperas.
Pengembang memahami bahwa memperbaiki bug nanti lebih mahal, tetapi balikkan saja. Jika Anda dapat dibayar $ 500 sehari untuk kode cara Anda kode sekarang atau $ 1000 jika Anda menulis dengan cara TDD, Anda akan menggigit tangan orang yang membuat Anda tawaran ke-2. Semakin cepat Anda berhenti melihat pengujian sebagai tugas dan melihatnya sebagai penghemat uang, semakin baik Anda.
sumber
Saya dapat menghubungkannya dengan expierience Anda - basis kode kami hampir tidak memiliki tes dan sebagian besar tidak dapat diuji. Butuh waktu lama untuk mengembangkan sesuatu dan memperbaiki bug produksi butuh waktu berharga dari fitur baru.
Untuk penulisan ulang parsial, saya berjanji untuk menulis tes untuk semua fungsionalitas inti. Pada awalnya, butuh waktu lebih lama dan produktivitas saya sangat terasa, tetapi setelah itu produktivitas saya lebih baik daripada sebelumnya.
Bagian dari peningkatan itu adalah saya memiliki lebih sedikit bug produksi yang pada gilirannya menyebabkan lebih sedikit gangguan -> Saya memiliki fokus yang lebih baik pada waktu tertentu.
Selain itu, kemampuan untuk menguji dan men-debug kode dalam isolasi benar-benar terbayar - serangkaian tes jauh lebih unggul daripada sistem yang tidak dapat di-debug kecuali dengan pengaturan manual, misalnya meluncurkan aplikasi Anda dan menavigasi ke layar dan melakukan sesuatu ... mungkin beberapa lusin kali
Tetapi perhatikan bahwa ada penurunan produktivitas di awal, jadi mulailah mempelajari pengujian pada beberapa proyek di mana tekanan waktu belum gila. Selain itu, cobalah untuk memulainya pada proyek greenfield, unit menguji kode lama sangat sulit, dan ini membantu ketika Anda tahu bagaimana bentuk suite pengujian yang baik.
sumber
Sekadar melengkapi jawaban sebelumnya: ingatlah bahwa pengujian bukanlah tujuan itu sendiri. Tujuan membuat tes adalah agar aplikasi Anda berperilaku seperti yang diharapkan melalui evolusi, dalam konteks yang tidak terduga, dll.
Oleh karena itu, tes menulis tidak berarti membuktikan semua perilaku dari semua titik akhir suatu entitas. Ini adalah kesalahan umum. Banyak pengembang berpikir mereka perlu menguji semua fungsi / objek / metode / properti / dll. Ini mengarah pada beban kerja yang tinggi dan banyak kode serta tes yang tidak relevan. Pendekatan ini umum dalam proyek-proyek besar, di mana sebagian besar pengembang tidak menyadari perilaku holistik, tetapi hanya dapat melihat domain interaksi mereka.
Pendekatan yang tepat ketika berhadapan dengan sumber daya yang jarang dan pengujian cukup jelas dan masuk akal, tetapi tidak umum diformalkan: investasi pengujian sumber daya pengembangan pertama pada fungsi tingkat tinggi, dan secara bertahap turun ke kekhususan . Ini berarti bahwa pada titik tertentu, sebagai pengembang yang kesepian, Anda tidak hanya akan fokus pada pengujian unit, tetapi pada fungsional / integrasi / dll. menguji dan tergantung pada sumber daya waktu Anda, secara bertahap ke dalam fungsi kesatuan utama, seperti yang Anda rencanakan dan pertimbangkan. Pengujian tingkat tinggi akan memberikan informasi yang diperlukan untuk mengatasi pengujian tingkat rendah / kesatuan dan untuk merencanakan strategi pengembangan pengujian Anda sesuai dengan sumber daya yang Anda miliki.
Misalnya, Anda ingin menguji rantai pemrosesan terlebih dahulu sebagai kotak hitam. Jika Anda menemukan bahwa beberapa anggota rantai gagal karena perilaku tidak dianggap sebagai kondisi ekstrem, Anda menulis tes yang menjamin fungsionalitas tidak hanya pada anggota ini tetapi juga pada yang lain. Lalu Anda memberikan. Untuk siklus berikutnya, Anda mendeteksi bahwa terkadang jaringan gagal. Jadi, Anda menulis tes yang membahas masalah seperti itu pada modul yang mungkin rentan. Dan seterusnya.
sumber