Apakah test driven development (TDD) benar-benar menguntungkan proyek dunia nyata?

36

Saya bukan orang baru dalam coding. Saya telah mengkode (serius) selama lebih dari 15 tahun sekarang. Saya selalu memiliki beberapa pengujian untuk kode saya. Namun, selama beberapa bulan terakhir saya telah belajar test driven design / development (TDD) menggunakan Ruby on Rails . Sejauh ini, saya tidak melihat manfaatnya.

Saya melihat beberapa manfaat untuk menulis tes untuk beberapa hal, tetapi sangat sedikit. Dan sementara saya suka ide untuk menulis tes pertama, saya menemukan saya menghabiskan lebih banyak waktu mencoba debug tes saya untuk membuat mereka mengatakan apa yang sebenarnya saya maksudkan daripada saya debugging kode yang sebenarnya. Ini mungkin karena kode tes seringkali jauh lebih rumit daripada kode yang diuji. Saya harap ini hanya pengalaman dengan alat yang tersedia ( RSpec dalam hal ini).

Saya harus mengatakan, pada titik ini, tingkat frustrasi bercampur dengan kurangnya kinerja yang mengecewakan tidak dapat diterima. Sejauh ini, satu-satunya nilai yang saya lihat dari TDD adalah pustaka yang tumbuh dari file RSpec yang berfungsi sebagai templat untuk proyek / file lain. Yang tidak jauh lebih bermanfaat, mungkin kurang bermanfaat, daripada file kode proyek yang sebenarnya.

Dalam membaca literatur yang tersedia, saya perhatikan bahwa TDD tampaknya adalah waktu yang sangat besar di depan, tetapi terbayar pada akhirnya. Saya hanya ingin tahu, apakah ada contoh dunia nyata? Apakah frustrasi besar ini pernah terbayar di dunia nyata?

Saya benar-benar berharap saya tidak melewatkan pertanyaan ini di tempat lain di sini. Saya mencari, tetapi semua pertanyaan / jawaban sudah beberapa tahun pada saat ini. Itu adalah kesempatan langka ketika saya menemukan pengembang yang akan mengatakan hal buruk tentang TDD, itulah sebabnya saya menghabiskan banyak waktu untuk ini seperti yang saya miliki. Namun, saya perhatikan bahwa tampaknya tidak ada yang menunjuk pada contoh dunia nyata tertentu. Saya memang membaca satu jawaban yang mengatakan orang itu men-debug kode pada 2011 akan berterima kasih untuk memiliki suite pengujian unit lengkap (saya pikir komentar itu dibuat pada 2008).

Jadi, saya hanya ingin tahu, setelah bertahun-tahun, apakah kita akhirnya memiliki contoh yang menunjukkan bahwa imbalannya nyata? Adakah yang benar-benar mewarisi atau kembali ke kode yang dirancang / dikembangkan dengan TDD dan memiliki serangkaian unit test lengkap dan benar-benar merasakan hasil? Atau apakah Anda mendapati bahwa Anda menghabiskan begitu banyak waktu untuk mencari tahu apa tes yang diuji (dan mengapa itu penting) sehingga Anda hanya membuang seluruh kekacauan dan menggali ke dalam kode?

James
sumber
1
Ini menyelamatkan saya lebih banyak waktu: karena kita banyak orang di proyek yang sama, karena pembaruan permata mungkin memiliki beberapa efek samping yang tidak diketahui, karena jika semuanya berwarna hijau dan saya memiliki bug, saya tahu di mana tidak layak untuk menemukan itu root.
Apneadiving
3
butunclebob.com/ArticleS.UncleBob.JustTenMinutesWithoutAtest Ini adalah cerita dari Paman Bob tentang situasi dunia nyata yang dia hadapi.
Hakan Deryal
1
Pada awalnya, saya pikir tes akan bagus untuk mengetahui di mana bug tidak, tetapi saya segera belajar, seperti yang ditunjukkan oleh @Hakan dalam artikel Paman Bob, umumnya muncul karena Anda melewatkan sebuah test case. Yang membuat tes itu sangat tidak berguna. Faktanya, artikel itu menunjukkan bahwa Pembangunan Bertambah adalah yang berfungsi.
James
1
"Saya menemukan saya menghabiskan lebih banyak waktu mencoba men-debug tes saya untuk membuat mereka mengatakan apa yang sebenarnya saya maksudkan daripada melakukan debug kode yang sebenarnya" : tetapi bukankah ini justru manfaatnya? Setelah itu, apakah Anda masih menemukan Anda menghabiskan banyak waktu men-debug "kode aktual"? Para pendukung TDD berpendapat bahwa waktu yang dihabiskan untuk mencari cara untuk membuat kode Anda dapat diuji sebenarnya merupakan upaya desain yang akan menguntungkan kode Anda.
Andres F.

Jawaban:

26

Makalah ini menunjukkan bahwa TDD menambahkan 15-35% waktu pengembangan sebagai imbalan untuk pengurangan 40-90% dalam kepadatan cacat pada proyek-proyek lain yang disukai.

Artikel tersebut merujuk makalah lengkap (pdf) - Nachiappan Nagappan, E. Michael Maximilien, Thirumalesh Bhat, dan Laurie Williams. "Menyadari peningkatan kualitas melalui pengembangan yang digerakkan oleh tes: hasil dan pengalaman dari empat tim industri". ESE 2008 .

AbstrakTest-driven development (TDD) adalah praktik pengembangan perangkat lunak yang telah digunakan secara sporadis selama berpuluh-puluh tahun. Dengan praktik ini, seorang insinyur perangkat lunak melakukan siklus menit per menit antara penulisan unit gagal tes dan penulisan kode implementasi untuk lulus tes tersebut. Pengembangan Testdriven baru-baru ini muncul kembali sebagai praktik penting yang memungkinkan dari metodologi pengembangan perangkat lunak tangkas. Namun, sedikit bukti empiris yang mendukung atau membantah kegunaan praktik ini dalam konteks industri. Studi kasus dilakukan dengan tiga tim pengembangan di Microsoft dan satu di IBM yang telah mengadopsi TDD. Hasil studi kasus menunjukkan bahwa kepadatan cacat pra-rilis dari empat produk menurun antara 40% dan 90% dibandingkan dengan proyek serupa yang tidak menggunakan praktik TDD. Secara subyektif,

Makalah lengkap juga merangkum secara singkat studi empiris yang relevan pada TDD dan hasil tingkat tinggi mereka (bagian 3 Pekerjaan Terkait ), termasuk George dan Williams 2003, Müller dan Hagner (2002), Erdogmus et al. (2005), Müller dan Tichy (2001), Janzen dan Seiedian (2006).

agas
sumber
2
Per diskusi tentang Meta.StackOverflow , dapatkah Anda menambahkan informasi tambahan dari makalah yang mungkin relevan bagi penanya dan juga orang-orang masa depan yang menemukan pertanyaan ini?
Thomas Owens
2
@ThomasOwens, saya pikir kesimpulannya ("TDD menambahkan 15-35% waktu pengembangan sebagai imbalan untuk pengurangan 40-90% dalam kepadatan cacat") adalah informasi tambahan yang menjawab pertanyaan awal <_ <
4
Pos ini telah ditandai karena tidak berisi informasi yang memadai. Saya belum membaca makalahnya, tetapi tampaknya orang-orang menginginkan lebih banyak informasi ditambahkan ke badan jawabannya. Mungkin membahas lebih lanjut tentang kondisi spesifik yang digunakan dalam penelitian ini?
Thomas Owens
99% dari semua statistik adalah fiksi. : P Tapi sebenarnya ini tentang konteks. Pada tim seperti apa? Sekawanan besar Jawa devs biasa-biasa saja? Ya, saya percaya TDD akan membantu mereka dengan produktivitas. Tapi itu tidak berarti memiliki keterampilan arsitektur untuk merancang dan menilai kode yang kuat di tempat pertama tidak akan membantu mereka lebih lagi dan IMO, TDD pertama yang diuji bisa dengan mudah mencegah mereka dari pernah belajar bagaimana melakukan itu dengan benar. Dan ya, saya pernah mendengar bahwa itu membantu dalam desain. Untuk tingkat tertentu, itu mungkin benar tetapi masih gagal untuk mengakui dan bantuan band untuk masalah root IMO.
Erik Reppen
akan lebih baik jika beberapa makalah terdaftar dari ACM Digital Library atau kata kunci yang digunakan untuk mesin pencari di sana ditambahkan. kita perlu lebih keras dalam jawaban kita ketika berbicara tentang lincah dan TDD
Rudolf Olah
16

Saya melihat beberapa manfaat untuk menulis tes untuk beberapa hal, tetapi sangat sedikit. Dan sementara saya suka ide untuk menulis tes pertama, saya menemukan saya menghabiskan lebih banyak waktu mencoba debug tes saya untuk membuat mereka mengatakan apa yang sebenarnya saya maksudkan daripada saya debugging kode yang sebenarnya.

Saya telah bekerja TDD selama tiga tahun terakhir, dan pengalaman saya justru sebaliknya. Saya menghabiskan lebih sedikit waktu untuk menulis tes unit yang saya harus debug kode, seandainya saya tidak menulis tes unit.

Saya tidak hanya melakukan TDD, saya bekerja di luar-dalam, yaitu saya pertama kali mengimplementasikan TDD layer top / gui. Menerapkan lapisan atas menentukan persyaratan untuk lapisan berikutnya dalam sistem, yang saya kembangkan menggunakan TDD, dll. Sampai semua kode yang diperlukan untuk fitur tersebut telah diimplementasikan. Seringkali, saya mengalami hal itu setelah saya mengimplementasikan fitur seperti ini, dan saya merokok menguji fitur di sistem yang sebenarnya, itu berfungsi pertama kali. Tidak selalu, tetapi sering.

Dan mengingat bahwa merokok jauh lebih lama untuk menguji fitur dalam sistem sebenarnya daripada yang diperlukan untuk menjalankan beberapa tes unit, saya menghemat banyak waktu. Sebenarnya lebih cepat bagi saya untuk mengimplementasikan fitur menggunakan TDD daripada tidak mengimplementasikan fitur tidak menulis tes unit sama sekali.

Tetapi tes unit menulis adalah keterampilan yang harus dipelajari dan dikuasai, sama seperti keterampilan pemrograman lainnya. Ketika saya mulai melakukan TDD, saya memiliki 12 tahun pengalaman profesional dalam pemrograman, dan saya adalah programmer yang sangat berpengalaman. Saya pikir menulis suite uji besar untuk kode sistem akan menjadi hal yang sederhana. Tetapi ketika jumlah kode tes bertambah, dan bagian-bagian berbeda dari sistem berubah, dan tes yang ada harus dimodifikasi, saya belajar bahwa menyusun dan menulis unit test itu sendiri merupakan keterampilan yang harus dipelajari dan dikuasai. Juga tidak semua kode sama-sama dapat diuji. Kode sistem harus sangat longgar digabungkan agar dapat diuji secara efisien. Sebenarnya belajar TDD telah membantu saya membuat kode sistem lebih longgar.

Tetapi efisiensi saya saat ini dalam bekerja TDD berasal dari kombinasi keduanya menguasai cara menulis tes unit, tetapi juga menguasai teknologi sistem diimplementasikan dalam (C # dalam kasus ini).

Melakukan TDD sambil mempelajari teknologi baru bisa sulit, misalnya meskipun saya sudah melakukan sedikit pemrograman iPhone, saya tidak menulis sejumlah besar unit test, karena saya tidak menguasai bahasa, objektif c, dan saya juga tidak menguasai Perpustakaan. Jadi saya tidak tahu bagaimana menyusun tes unit saya, apalagi bagaimana menyusun kode sistem bagaimana membuatnya bisa diuji.

Tetapi seberapa baik kerjanya pada proyek nyata?

Pada proyek yang telah saya kerjakan selama beberapa tahun terakhir, meskipun ada persyaratan bahwa kode harus cukup dicakup oleh unit test, saya satu-satunya di tim yang menulis tes pertama. Tetapi test suite besar memberi saya kepercayaan diri untuk dapat memperbaiki sistem, dan yakin sistem akan bekerja dengan benar jika test suite lulus.

Tetapi sayangnya karena banyak tes ditulis setelah kode sistem, beberapa tes sendiri salah, yaitu mereka tidak benar-benar menguji apa yang seharusnya mereka uji. Imho ini tidak bisa dihindari. Setiap kali Anda menulis sepotong kode, ada kemungkinan kode tidak berfungsi seperti yang Anda inginkan, yaitu ada bug. Hal yang sama berlaku untuk kode uji. Oleh karena itu ada kemungkinan Anda menulis tes yang lulus meskipun kode yang seharusnya diuji tidak berfungsi sebagaimana dimaksud.

Menulis tes terlebih dahulu, memverifikasi bukan hanya bahwa Anda mendapatkan kegagalan tes, tetapi bahwa tes gagal dengan pesan kesalahan yang Anda harapkan sebelum menerapkan kode sistem secara serius mengurangi risiko bug dalam kode tes unit.

Jadi singkatnya, dalam pengalaman saya setelah Anda menguasai seni TDD, Anda tidak hanya akan menghemat waktu dalam jangka panjang, Anda akan menghemat waktu di depan. Tetapi butuh waktu, bahkan untuk seorang programmer yang berpengalaman, untuk menguasai seni TDD. Dan bahkan dibutuhkan waktu lebih lama bagi tim pengembang dengan berbagai keterampilan untuk menguasai seni TDD.

Pete
sumber
9

Kami mendapat manfaat besar-besaran.

Kami adalah Pedagang Tingkat 1, yang berarti kami memproses lebih dari enam juta transaksi pembayaran per tahun.

Sistem gateway pembayaran kami memiliki ribuan unit dan tes integrasi. Tes ini memberi kami kepercayaan diri pada kemampuan kami untuk memproses pembayaran. Anda ingin yakin bahwa rem mobil Anda berfungsi, bukan? Kami ingin yakin bahwa kami tidak kehilangan bisnis kami karena kami tidak dapat memproses pembayaran.

Cakupan kode memberi Anda kepercayaan diri itu. Tentu saja itu tidak cukup sendiri, tapi ini awal yang sangat bagus.

Sebagian besar sistem gateway pembayaran kami ditulis menggunakan TDD. Beberapa aspek agak sulit untuk diuji, jadi kami telah memutuskan untuk mengambil jalan pintas dengan mengorbankan beberapa cakupan kode. Kami akan kembali dan mengatasi masalah ini pada akhirnya.

Secara pribadi, saya merasa sulit untuk menulis logika apa pun sebelum menulis tes. Karena itu, saya butuh sedikit waktu untuk mulai berpikir dengan cara TDD.

Referensi PCI PCI: http://usa.visa.com/merchants/risk_management/cisp_merchants.html

CodeART
sumber
3
"Kami akan kembali dan mengatasi masalah ini pada akhirnya." - mungkin tidak ... tidak, kecuali mereka menyebalkan menamparmu dengan beberapa bug yang mengerikan. Area-area ini akan menjadi tulang punggung untuk segala sesuatu yang lain dan akan memandu semua desain bergerak maju karena tidak ada yang mau menginvestasikan sumber daya untuk mengulanginya dan tidak ada yang ingin memaksakan setiap perubahan yang mungkin melakukan sesuatu yang buruk. Terjadi setiap waktu: P
Edward Strange
Anda menebak, ketika saya memberi tahu Anda apa yang terjadi di dalam perusahaan. Ketika kita komit, kita bisa mengkomit kode dengan cakupan kode 70%. Ini terus-menerus ditingkatkan dengan memimpin CI. Dalam beberapa bulan, ambang batas cakupan kode minimum akan ditingkatkan dengan persentase kecil. Setelah itu tidak akan ada pilihan, selain memperkenalkan lebih banyak tes.
CodeART
7

Meskipun tes mungkin sering dianggap hanya sebagai cara untuk melakukan terlalu banyak oleh beberapa orang, saya pikir itu benar-benar sepadan dengan masalah dalam kasus-kasus tertentu.

Saya telah mengembangkan Solver Sudoku Solver untuk sekolah selama sekitar 3 bulan, ia menggunakan banyak "strategi" untuk menghilangkan kemungkinan dan solusi. Faktanya adalah, kesalahan dalam suatu kemungkinan bisa berakibat fatal dan mengakibatkan masalah untuk menyelesaikan sudoku karena ketika beberapa kemungkinan dihapus, Anda tidak mencobanya lagi, dan jika itu solusinya, program tidak dapat menyelesaikannya. grid lagi.

Tapi itu sangat sulit untuk menguji secara manual, maksud saya benar ada kotak, saya bisa melihat strategi yang melakukan apa dalam contoh dunia nyata, tapi saya tidak bisa memeriksa setiap kali strategi diterapkan karena ini mewakili terlalu banyak data.

Dan strategi yang diterapkan pada grid tertentu cukup "acak", artinya Anda tidak akan menggunakan semuanya pada grid tertentu.

Jadi saya menulis tes pada setiap strategi, memeriksa hasilnya pada setiap sel, hanya menggunakan situasi sederhana (misalnya hanya dua sel yang sudah menghilangkan kemungkinan) dan itu menyelamatkan saya berjam-jam sehari ketika saya sayangnya memiliki kotak yang tidak dapat diselesaikan. Karena saya sudah tahu di mana masalahnya.

Cydonia7
sumber
2
Saya merasa pertanyaan ini lebih menyodok pada tes pertama, menerapkan stratergy nanti. Tes tentu saja berguna untuk men-debug aplikasi di mana itu akan membosankan untuk menguji setiap kemungkinan sendiri.
Alex Hope O'Connor
6

Keuntungan dari TDD adalah Anda mengetahui cara memanggil kode sebelum menulis kode yang sebenarnya.

Dengan kata lain, TDD membantu merancang API Anda.

Dalam pengalaman saya ini menghasilkan API yang lebih baik yang pada gilirannya memberikan kode yang lebih baik.


EDIT: Seperti yang saya tulis, ini "dalam pengalaman saya", yaitu ketika menulis "proyek dunia nyata" tapi sayangnya ini dengan basis kode sumber tertutup saya tidak bisa membiarkan dunia melihat. Saya dapat memahami dari komentar bahwa ini adalah apa yang sebenarnya diminta, dan bukan hanya konfirmasi tentang keberadaan proyek semacam itu.

Saya juga menemukan - lagi dalam pengalaman pribadi saya - bahwa manfaat nyata menunjukkan ketika Anda memasuki mode pemeliharaan karena persyaratan cenderung berubah. API pembersih membuatnya lebih mudah untuk mengekspresikan persyaratan baru atau yang diubah dalam kode uji, dan semua tes membuatnya sangat mudah untuk melihat bagi pengelola masa depan bagaimana kode dipanggil dan apa yang dapat diharapkan kembali.

Kasing uji menjalankan versi spesifikasi dan memungkinkan Anda untuk melihat dengan sangat, sangat mudah bagaimana memohon API Anda. Ini mungkin satu-satunya bentuk dokumentasi "HOW" yang paling berguna yang pernah saya lihat sejauh ini (dibandingkan dengan dokumentasi "MENGAPA" seperti JavaDoc) karena Anda yakin itu benar (jika tidak, tes akan gagal).

Akhir-akhir ini, saya harus memelihara klien ftp skrip dengan serangkaian opsi yang sangat besar yang semuanya memengaruhi cara kerja aplikasi. TDD telah diperkenalkan akhir-akhir ini untuk fungsionalitas baru dan rangkaian uji besar memungkinkan kami untuk melakukan perbaikan terbaru sambil yakin bahwa fungsionalitas yang digunakan masih berfungsi seperti yang diharapkan. Dengan kata lain transisi ini terbukti membuahkan hasil dengan sangat cepat.


sumber
8
Jawaban ini tampaknya sepenuhnya berada di samping pertanyaan, karena pertanyaan tersebut membutuhkan contoh dunia nyata . Tetapi karena tiga orang berpikir "jawaban ini berguna", saya pasti kehilangan sesuatu.
3
Setuju, tetapi saya tidak memiliki reputasi untuk memilih. Ini hanya "TDD memberikan hasil yang lebih baik" tanpa contoh proyek turunan TDD dalam pemeliharaan untuk mendukungnya jawaban yang ingin saya hindari.
James
Sekarang beberapa orang setuju dengan saya, saya berani mengalah. Apakah ada orang yang memilih, atau penulis, silakan maju dan memberi tahu kami mengapa ini adalah jawaban yang bagus?
@delnan "Saya berani mengalah" - pilihan kata yang menarik. Apakah hasil edit sesuai selera Anda?
Ya, saya menghapus downvote saya sekarang setelah saya perhatikan.
5

Seberapa berharganya suatu pendekatan khusus untuk pengujian tergantung pada seberapa kritis misi sistem yang sedang dikembangkan, dan seberapa banyak beberapa sistem kritis misi lainnya bergantung padanya. Skrip buku tamu sederhana untuk situs web Anda hampir tidak dapat dianggap sebagai misi kritis, tetapi jika situs web itu berjalan dapat berpotensi dikompromikan oleh bug yang memungkinkan input tanpa filter ke database dan situs itu menawarkan beberapa layanan penting, maka tiba-tiba itu menjadi jauh lebih banyak. penting untuk skrip buku tamu untuk diuji secara menyeluruh. Hal yang sama juga berlaku untuk kode framework / library. Jika Anda mengembangkan kerangka kerja dengan bug, maka setiap aplikasi yang menggunakan fitur kerangka kerja itu juga memiliki bug yang sama.

Pengembangan yang digerakkan oleh tes memberi Anda lapisan keselamatan tambahan saat melakukan tes. Jika Anda menulis tes di samping atau bahkan setelah kode yang ingin Anda uji, maka ada risiko nyata bahwa Anda salah tes. Jika Anda menulis semua tes terlebih dahulu, lalu bagaimana kode bekerja secara internal tidak dapat memengaruhi apa yang Anda tulis untuk tes, dan oleh karena itu ada sedikit kemungkinan bahwa Anda secara tidak sengaja menulis tes yang berpikir bahwa output yang salah tertentu benar.

Pengembangan yang digerakkan oleh tes juga mendorong pengembang Anda untuk menulis kode yang mudah diuji, karena mereka tidak ingin memberikan lebih banyak pekerjaan kepada diri mereka sendiri! Kode yang mudah diuji cenderung menjadi kode yang mudah dipahami, digunakan kembali, dan dipelihara.

Dan pemeliharaan adalah tempat Anda benar-benar akan menuai hasil TDD. Sebagian besar upaya pemrograman yang dikeluarkan untuk perangkat lunak terkait dengan pemeliharaan. Ini berarti membuat perubahan pada kode langsung untuk memberikan fitur baru, memperbaiki bug, atau menyesuaikannya dengan situasi baru. Saat membuat perubahan seperti itu, Anda ingin memastikan bahwa perubahan yang Anda buat memiliki efek yang diinginkan, dan yang lebih penting, mereka tidak memiliki ketukan efek yang tidak terduga. Jika Anda memiliki rangkaian uji lengkap untuk kode Anda, maka mudah untuk memverifikasi bahwa setiap perubahan yang Anda buat tidak merusak sesuatu yang lain, dan jika perubahan yang Anda lakukan merusak sesuatu yang lain maka Anda dapat dengan cepat menemukan alasannya. Manfaatnya jangka panjang.

Anda mengatakan hal berikut dalam pertanyaan Anda:

Saya melihat beberapa manfaat untuk menulis tes untuk beberapa hal, tetapi sangat sedikit. Dan sementara saya suka ide untuk menulis tes pertama, saya menemukan saya menghabiskan lebih banyak waktu mencoba debug tes saya untuk membuat mereka mengatakan apa yang sebenarnya saya maksudkan daripada saya debugging kode yang sebenarnya. Ini mungkin karena kode tes seringkali jauh lebih rumit daripada kode yang diuji. Saya harap ini hanya pengalaman kurang dengan alat yang tersedia (rspec dalam hal ini).

Ini sepertinya menyarankan kepada saya bahwa Anda tidak cukup mendapatkan pengujian. Tes unit seharusnya sangat sederhana, hanya urutan panggilan metode, diikuti oleh pernyataan untuk membandingkan hasil yang diharapkan dengan hasil yang sebenarnya. Mereka dimaksudkan untuk menjadi sederhana karena bug dalam tes Anda akan menjadi bencana, dan jika Anda memperkenalkan loop, percabangan atau program lain melempar kontrol ke dalam tes, maka kemungkinan besar tes tersebut akan memasukkan bug ke dalamnya. Jika Anda menghabiskan banyak waktu men-debug tes maka itu menunjukkan bahwa tes Anda terlalu rumit dan Anda harus menyederhanakannya.

Jika tes tidak dapat disederhanakan, daripada fakta itu saja menunjukkan bahwa ada sesuatu yang salah dengan kode yang diuji. Sebagai contoh jika kelas Anda memiliki metode yang panjang, metode dengan banyak if / elseif / else atau beralih pernyataan atau sejumlah besar metode yang memiliki interaksi kompleks yang ditentukan oleh keadaan kelas saat ini, maka tes yang diperlukan harus sangat kompleks. untuk memberikan cakupan kode lengkap dan menguji semua kemungkinan. Jika kelas Anda memiliki ketergantungan kode keras pada kelas lain maka ini lagi akan meningkatkan jumlah simpai Anda harus melompat untuk menguji kode Anda secara efektif.

Jika Anda menjaga kelas Anda kecil dan sangat fokus, dengan metode pendek dengan beberapa jalur eksekusi dan mencoba menghilangkan keadaan internal maka tes dapat disederhanakan. Dan ini adalah inti permasalahannya. Kode yang baik pada dasarnya mudah untuk diuji. Jika kodenya tidak mudah untuk diuji, mungkin ada sesuatu yang salah dengannya.

Tes unit menulis adalah sesuatu yang bermanfaat bagi Anda dalam jangka panjang, dan menghindarinya hanyalah menyimpan masalah untuk nanti. Anda mungkin tidak terbiasa dengan konsep utang teknis, tetapi ini sangat mirip dengan utang finansial. Tidak menulis tes, tidak berkomentar kode, menulis dalam dependensi kode keras dan sebagainya adalah cara-cara masuk ke hutang. Anda "meminjam" waktu dengan mengambil jalan pintas sejak dini dan ini mungkin membantu Anda mencapai tenggat waktu yang ketat, tetapi waktu yang Anda hemat sebelumnya dalam proyek adalah pinjaman. Setiap hari berlalu tanpa membersihkan kode, mengomentari dengan benar, atau membangun test suite akan membuat Anda tertarik. Semakin lama berlangsung, semakin banyak bunga terakumulasi. Akhirnya, Anda akan menemukan kode Anda telah menjadi kekacauan kusut yang tidak dapat Anda ubah tanpa memicu konsekuensi yang tidak diinginkan.

Anda dapat berpikir untuk menulis unit test lebih awal dan menjadikannya terbaru sebagai bentuk "kredit teknis". Anda menempatkan waktu di bank dengan membelanjakannya di awal proyek untuk mengikuti praktik yang baik. Anda akan mendapatkan bunga pada tinjauan ke depan ini nanti ketika Anda sampai ke fase pemeliharaan proyek. Ketika Anda ingin melakukan perubahan, Anda dapat dengan mudah memvalidasi kebenaran perubahan dan bahwa itu tidak memiliki efek samping yang tidak diinginkan, dan Anda bisa mendapatkan pembaruan keluar pintu dengan cepat dan tanpa keributan. Jika bug muncul, Anda dapat menambahkan unit test baru yang melatih bug, lalu perbaiki bug dalam kode. Ketika berikutnya Anda menjalankan unit test Anda akan dapat memverifikasi bahwa bug telah diperbaiki, dan bahwa itu tidak menyebabkan masalah lain. Lebih jauh lagi, Anda akan menghindari "regresi",

TL: DR - Ya, mereka adalah bantuan dunia nyata, tetapi mereka adalah investasi. Manfaatnya baru terlihat kemudian.

GordonM
sumber
1
Saya membeli logika ini berbulan-bulan yang lalu. Saya suka ide di balik TDD, saya hanya menemukan kenyataan sedikit membingungkan. Juga, saya perhatikan bahwa bahkan di sini, tidak ada contoh aktual di mana mewarisi proyek berbasis TDD telah terbayar. Apakah Anda benar-benar kembali ke basis kode lama yang memiliki banyak tes unit dan hasilnya terbayar.
James
Sayangnya tidak, karena tidak ada orang lain yang tampaknya membangun unit test, setidaknya tidak pada kode yang saya warisi dari pengembang sebelumnya. Hidupku akan jauh lebih mudah jika mereka melakukannya. Saya sarankan Anda memeriksa buku di tautan, yang memang memiliki contoh dunia nyata, meskipun itu untuk PHP daripada Rails. amazon.com/…
GordonM
Saya seorang kritikus besar penggunaan umum tetapi saya tidak akan menyalahkan siapa pun untuk menggunakan pendekatan ini dalam sistem keuangan yang tertanam atau kritis.
Erik Reppen
4

Saya cukup sering menggunakan TDD di tempat kerja. Pengalaman saya adalah bahwa TDD membenarkan dirinya sendiri karena Anda tidak membayar waktu atau usaha tambahan, Anda menghematnya .

  • Karena saya menggunakan TDD, saya menghabiskan lebih sedikit waktu untuk debugging atau semacamnya. Ini hanya berfungsi sejak awal karena saya tidak menganggap kode produktif ditulis selama tes tidak lulus.

  • QA melaporkan lebih sedikit bug, jadi kami menghemat biaya untuk memperbaiki kode kami setelah rilis. Ini karena TDD tidak membiarkan Anda menulis kode tanpa tes sehingga cakupan kode jauh lebih baik.

  • Saya dapat menjalankan kode (produktif) saya lebih sering dan lebih cepat karena saya tidak perlu memulai seluruh server aplikasi. Memulai tes unit adalah urutan besarnya lebih cepat. Tentu saja saya hanya mendapat manfaat dari itu ketika tes sudah dapat dieksekusi ketika saya ingin mencoba kode produktif. Ketika tes datang sesudahnya, manfaat ini terlewatkan.

  • Saya melakukan pengujian manual jauh lebih sedikit. Rekan-rekan saya yang tidak berlatih TDD menghabiskan banyak waktu mengklik aplikasi hingga mereka mencapai titik di mana kode baru dieksekusi. Saya hanya menguji secara manual sekali, tepat sebelum saya berkomitmen untuk kontrol versi.

  • Bahkan jika saya menggunakan debugger itu jauh lebih cepat untuk men-debug pelaksanaan tes daripada seluruh aplikasi.

Mungkin Anda menganggap tes unit sebagai tes regresi. Itu adalah salah satu tujuan mereka tetapi memahami mereka sebagai alat untuk pembangunan membuat mereka jauh lebih berharga.

Wolfgang
sumber
Kualitas gratis!
MathAttack
2
Kualitas buruk mahal!
Wolfgang
3

Keuntungan lain (selain dari yang disebutkan oleh orang lain yang menjawab) menendang ketika penguji penerimaan pelanggan, atau (surga melarang) pengguna produksi menemukan bug. Ubah laporan bug menjadi tes gaya TDD untuk kelas yang tampaknya salah. Tonton itu gagal. Memperbaikinya. Saksikan itu berlalu. Maka Anda tahu bahwa Anda telah memperbaiki bug. Teknik ini telah menghemat waktu saya.

Dawood berkata mengembalikan Monica
sumber
2

Yah, saya tahu bahwa secara pribadi saya mendapat manfaat dengan menjadi dua kali lebih cepat dari sesama pengembang dan menulis kurang dari setengah bug yang mereka lakukan karena mereka TIDAK melakukan TDD. Orang yang mungkin harus lebih baik daripada saya bahkan ... Saya mengungguli mereka dengan setidaknya faktor 2.

Saya tidak sampai di sana segera. Saya cukup pandai menulis kode dari borgol dan tanpa harness. Tampak seperti sampah besar untuk menulis semua omong kosong tambahan ini. Tetapi ia melakukan beberapa hal, termasuk (tidak eksklusif):

  • Memaksa desain yang diarahkan pada decoupling dan digunakan kembali (semuanya harus digunakan kembali dalam unit test).
  • Menyediakan platform untuk mengembangkan kode dalam bongkahan kecil dan modul, jadi saya tidak perlu menyelesaikan semuanya sebelum menyelesaikan tes sederhana "Apakah itu mengkompilasi dan menerima input".
  • Menyediakan platform pengujian cepat untuk membuat perubahan ketika orang menuntut perubahan fitur yang tidak saya harapkan.

Contoh pada bit belakangan ini adalah proyek yang saat ini saya kerjakan dimana pemimpinnya tiba-tiba memutuskan untuk BENAR-BENAR menulis ulang protokol komunikasi yang digunakannya untuk alasan 0. Saya dapat menanggapi perubahan itu dalam 2 jam karena saya telah memisahkannya dari yang lainnya dan mampu mengerjakannya sepenuhnya secara independen sampai yang terakhir mengikatnya bersama-sama dan mengintegrasikannya mengujinya. Sebagian besar rekan kerja saya mungkin akan melakukannya selama satu hari atau lebih karena kode mereka tidak akan dipisahkan dan mereka akan berubah di sini, di sana, di mana-mana ... kompilasi semuanya ... pengujian integrasi ... ulangi, ulangi ... Dibutuhkan jauh lebih lama seperti itu dan tidak ada yang mendekati stabil.

Edward Strange
sumber
2

Jawabannya iya. Di perusahaan saya, kami telah mengembangkan aplikasi C ++ selama lebih dari 20 tahun. Tahun lalu, kami masuk ke TDD di beberapa modul baru, dan tingkat cacat menurun secara signifikan. Kami sangat menyukainya sehingga beberapa dari kami bahkan menambahkan tes ke kode lawas setiap kali kami mengubah sesuatu di sana.

Selain itu, seluruh modul diselesaikan dari awal hingga selesai, melalui produksi, tanpa pernah menunjukkan bug (dan itu juga modul penting). Dengan demikian pengembangannya lebih cepat dari biasanya, karena biasanya yang akan terjadi adalah modul akan "selesai", hanya untuk mengembalikan 4-5 kali dari pengujian beta untuk perbaikan bug. Itu adalah peningkatan yang substansial, dan para pengembang lebih senang dengan proses baru juga.

Saya belum melakukan banyak Rails TDD, tapi saya sudah melakukan banyak hal di C ++, C #, Java dan Python. Saya dapat memberitahu Anda bahwa itu pasti berhasil. Dugaan saya adalah bahwa Anda menghabiskan banyak waktu untuk memikirkan nama ujian karena Anda tidak cukup percaya diri. Tulis dulu tes Anda, tetapi biarkan kreativitas Anda mengalir ...

Saya perhatikan bahwa begitu Anda benar-benar memahami TDD, Anda mulai sedikit peduli pada "Bagaimana saya akan menamai tes ini ... argh!", Dan Anda hanya mengalir dengannya, refactoring dan beradaptasi yang sudah ditulis tes agar sesuai dengan situasi saat ini.

Waktunya tip

Kiat # 1

Jadi tip yang menurut saya paling membantu Anda adalah jangan terlalu khawatir. Salah satu hal tercantik tentang TDD adalah memberi Anda keberanian untuk mengubah hal-hal yang sudah ditulis dan berfungsi. Dan itu termasuk tes.

Kiat # 2

Mulailah tes kelas baru dengan tes "canCreate" sederhana, hanya untuk mengarahkan pikiran Anda ke arah yang benar, seperti dalam "Oke, saya sedang mengerjakan kelas ini sekarang ... benar."

Kemudian mulailah menambahkan lebih banyak tes, tetapi hanya satu per satu, dan pastikan bahwa setiap tes yang Anda buat, itu adalah kasus paling sederhana berikutnya yang muncul di pikiran Anda pada saat itu (pikirkan tentang hal itu tidak lebih dari 30 detik, dan kemudian batas waktu dengan yang terbaik yang Anda miliki pada saat itu).

Dan ingatlah

Jangan khawatir tentang refactoring tes yang ada atau bahkan menghapus yang sudah usang atau berlebihan. Tidak banyak orang menyadari hal ini, tetapi dalam TDD Anda benar-benar mendapatkan 2 jaring pengaman dengan harga 1. Tes Anda adalah jaring pengaman untuk perubahan kode produksi, tetapi kode produksi Anda juga merupakan jaring pengaman untuk refactoring pengujian. Hubungan itu saling menguntungkan. Ini sebenarnya kasus kopling ketat yang bagus.

Cobalah lagi. Dan saya sarankan menonton Clean Code Casts , terutama yang tentang TDD.

Yam Marcovic
sumber
1

Contoh non-sepele dunia nyata:

Saya harus menulis fungsi transformasi struktur data. Input akan menjadi struktur data (sebenarnya struktur data bersarang, seperti pohon) dan output akan menjadi struktur data yang serupa. Saya tidak dapat memvisualisasikan transformasi aktual dalam pikiran saya. Salah satu manfaat utama TDD (bagi saya, bagaimanapun juga) adalah penegakan langkah-langkah kecil jika Anda tidak tahu bagaimana melanjutkan (lihat Kent Becks "TDD dengan Contoh"). Karena saya tidak tahu kemana ini akan pergi, saya mulai dengan kasing sederhana seperti input kosong atau sepele dan bekerja sampai kasing yang lebih rumit sampai saya pikir saya sudah membahas semuanya. Pada akhirnya saya memiliki algoritma yang berfungsi dan tes yang membuktikannya. Tidak hanya tes yang membuktikan bahwa implementasi saya berfungsi sekarang, mereka juga mencegah saya mengacaukan apa pun di kemudian hari.

EricSchaefer
sumber
-1

Saya tidak suka gagasan membabi buta mengikuti saran umum karena saya tidak percaya ada saran satu ukuran untuk semua yang akan membantu kebanyakan pengembang menjadi lebih produktif dan mengurangi cacat dalam aplikasi. Dari pengalaman saya, semakin Anda khawatir tentang kualitas semakin Anda akan kehilangan dalam jumlah fitur baru yang disampaikan. Jadi tingkat kepentingan yang ingin Anda berikan untuk kualitas vs hasil pengiriman akan benar-benar tergantung pada produk dan strategi Anda saat ini dan kemungkinan besar orang lain yang akan memutuskan secara strategis apa yang lebih penting untuk saat ini: ketahanan atau kemampuan pengiriman.

Bahkan keputusan ini tidak hitam atau putih. Kemungkinan besar beberapa bagian dari aplikasi Anda harus kuat sementara yang lain tidak harus. Setelah Anda mengidentifikasi bagian mana yang harus memiliki tingkat kualitas tinggi, Anda harus fokus pada mereka dari perspektif pengujian karena Anda ingin memastikan kualitas tinggi untuk bagian-bagian itu.

Semua yang saya katakan sejauh ini tidak ada hubungannya dengan TDD secara khusus dalam arti menulis tes sebelum implementasi, tetapi saya percaya penting untuk memisahkan manfaat memiliki kode yang diuji vs menulis tes terlebih dahulu.

Setelah Anda memahami manfaat pengujian itu sendiri, TDD atau tidak, Anda kemudian dapat membahas strategi pengujian untuk kode yang ingin Anda liput oleh tes. Beberapa orang akan berpendapat bahwa jika Anda menulis tes nanti Anda akan kehilangan beberapa kondisi dalam tes Anda, tetapi saya percaya Anda harus menjadi orang yang mengevaluasi apakah itu berlaku untuk Anda. Itu tentu tidak berlaku untuk saya.

Jadi, inilah cara kerjanya untuk saya. Pada dasarnya ada dua situasi yang akan membuat saya menulis tes: itu akan meningkatkan kualitas saja atau itu akan mempercepat pengembangan saya dari beberapa fitur juga. Jadi, situasi di mana saya akan menulis tes adalah ketika tidak ada fitur baru di backlog dan saya kemudian dapat memutuskan untuk meningkatkan kinerja aplikasi, menyederhanakan basis kode atau meningkatkan suite pengujian. Situasi lain adalah kebutuhan untuk memiliki kode kerja yang solid di mana bug akan memiliki dampak yang cukup besar pada klien nyata. Namun satu lagi adalah untuk menguji kode kompleks yang mudah rusak ketika mengerjakannya. Sebagai contoh, ada kelas QueryBuilder di basis kode saya yang menangani banyak kasus penggunaan dan akan mudah untuk memecahkan beberapa dari mereka saat memperbaiki bug atau menambahkan fitur baru.

Akhirnya, ada kasus di mana menulis tes pertama memungkinkan saya untuk menulis fitur lebih cepat daripada tidak menulis tes sama sekali. QueryBuilder itu juga merupakan kasus di mana aturan ini juga berlaku, tetapi itu tidak berarti TDD juga akan menjadi jalan terbaik. Contoh lain dari TDD membantu kecepatan pengembangan adalah untuk menguji generasi Excel misalnya, sedangkan dalam aplikasi nyata Anda mungkin harus melakukan beberapa langkah setiap kali Anda ingin menguji beberapa kondisi tertentu dalam generasi. Atau jika Anda perlu membuat beberapa catatan untuk menguji fitur dan sulit atau tidak mungkin untuk menghapusnya secara manual setelah Anda menguji kode secara manual.

Jadi, jika lebih mudah bagi Anda untuk mereproduksi langkah-langkah untuk menjalankan beberapa kode dalam-pengembangan secara programatis (melalui tes), lakukanlah. Tetapi jika menulis tes lebih rumit daripada mengujinya secara manual, maka Anda harus memutuskan apakah ini saatnya untuk fokus pada kualitas atau jika Anda memiliki banyak permintaan dalam jaminan Anda dan seseorang di perusahaan mungkin akan mengetahuinya lebih baik dan membiarkan Anda tahu di mana Anda harus fokus sesuai dengan kebutuhan mereka saat ini dan strategi perusahaan.

Dalam dunia yang ideal semua kode diuji, tetapi orang tidak bisa berpura-pura tidak ada trade-off dan menganggap bahwa TDD selalu jalan terbaik dan satu-satunya. Seperti halnya semua praktik terbaik di luar sana, Anda harus selalu fokus pada apa yang terbaik untuk perusahaan tempat Anda bekerja dan bukan apa yang lebih baik untuk Anda. Setelah Anda menjadi wiraswasta, Anda bebas memutuskan untuk melakukan TDD sepanjang waktu jika Anda pikir itu adalah jalan terbaik. Jika perusahaan Anda yakin semua kode harus diuji, maka Anda harus menulis tes untuk semua kode yang Anda tulis. Tetapi untuk sebagian besar kasus Anda harus mendapatkan gambaran besar dan memahami pertukaran sebelum Anda mengambil keputusan. Maaf, tapi ini bukan ilmu pasti dan tidak ada jawaban yang mudah (atau sulit) yang cocok untuk semua yang harus Anda ikuti setiap waktu.

Sama seperti dengan pola desain. Pahami bagaimana mereka bekerja dan mengapa mereka diciptakan dan masalah seperti apa yang mereka selesaikan dan apa kelemahan mereka juga. Memahami alasannya jauh lebih penting daripada mengingat solusi yang diusulkan. Apa yang merupakan operasi mahal hari ini dapat dengan mudah dicapai besok dengan teknologi lain. Jika premis untuk beberapa solusi mapan tidak lagi valid kemungkinan besar solusinya tidak lagi yang terbaik untuk digunakan. Ketika persyaratan, teknologi yang tersedia, atau strategi perusahaan telah berubah, Anda harus selalu mengevaluasi kembali kotak peralatan Anda dan ketika itu terjadi, Anda perlu memahami mengapa Anda memilih setiap jalur di tempat pertama alih-alih menganggapnya sebagai hibah sebagai pilihan terbaik.

rosenfeld
sumber
ini bahkan tidak berusaha untuk menjawab pertanyaan yang diajukan: "apakah kita akhirnya memiliki contoh yang menunjukkan pembayaran itu nyata? Apakah ada yang benar-benar mewarisi atau kembali ke kode yang dirancang / dikembangkan dengan TDD dan memiliki satu set lengkap unit test dan benar-benar merasakan imbalan? "
nyamuk
1
Itu menjawab, tetapi karena Anda tidak membagikan pendapat saya, Anda memberi -1 untuknya :) Pada dasarnya siapa pun yang tidak akan mencoba menunjukkan nilai-nilai TDD akan memberikan jawaban yang tidak diinginkan dari sudut pandang Anda;) Biarkan saya menebak . Anda seorang penginjil TDD, kan? :) Ngomong-ngomong, pertanyaan sebenarnya penulis adalah apakah TDD terbayar atau tidak. Anda tidak harus berlatih TDD untuk menjawabnya. Apakah Fortran membayar untuk menulis aplikasi web? Sudahkah Anda mencoba sebelum menjawab?
rosenfeld
Saya tidak memiliki pendapat tentang TDD, dan saya tidak menggunakan suara sebagai suka / tidak suka (ini adalah situs tanya jawab, bukan Facebook). Per bacaan saya, "jawaban" ini sama sekali tidak menjawab pertanyaan yang diajukan, baik secara positif maupun negatif
agas
Dari sudut pandang saya, ini bukan pertanyaan teknis, seperti "bagaimana saya melakukan X dengan nginx?". Ada jawaban yang tepat untuk pertanyaan seperti itu, tetapi tidak untuk pertanyaan kualitatif dan subyektif seperti ini, ketika penulis sebenarnya ingin mengetahui pendapat orang lain tentang TDD dan apakah itu layak. Itu adalah usaha saya untuk menunjukkan sudut pandang saya. Saya tidak tahu bagaimana jawaban bisa menjadi jawaban yang tepat karena semuanya sepertinya pendapat pribadi saya. Anda tidak dapat mengukur secara efektif apakah TDD layak atau tidak. Setiap artikel yang mencoba melakukan itu pada dasarnya salah.
rosenfeld
"Situs ini adalah semua tur yang mendapat jawaban . Ini bukan forum diskusi ..."
agas