Siklus Merah - Hijau - Reaktor untuk TDD telah ditetapkan dan diterima dengan baik. Kami menulis satu tes unit gagal dan membuatnya lulus sesederhana mungkin. Apa manfaat dari pendekatan ini daripada menulis banyak tes unit gagal untuk kelas dan membuat semuanya lulus sekaligus.
Test suite masih melindungi Anda dari penulisan kode yang salah atau membuat kesalahan di tahap refactoring, jadi apa salahnya? Terkadang lebih mudah untuk menulis semua tes untuk kelas (atau modul) terlebih dahulu sebagai bentuk 'brain dump' untuk dengan cepat menuliskan semua perilaku yang diharapkan dalam sekali jalan.
Jawaban:
Desain yang digerakkan oleh tes adalah tentang memperbaiki API Anda , bukan kode.
Manfaat dari menulis tes gagal paling sederhana pertama adalah bahwa Anda mendapatkan API Anda (yang pada dasarnya adalah Anda merancang dengan cepat) sesederhana mungkin. Di muka.
Segala kegunaan di masa depan (yang akan Anda tulis dalam tes selanjutnya) akan berasal dari desain sederhana awal, alih-alih desain yang optimal mengatasi kasus yang lebih kompleks.
sumber
Ketika Anda menulis satu tes, Anda berkonsentrasi pada satu hal.
Dengan banyak tes, Anda menyebarkan perhatian pada banyak tugas, jadi itu bukan ide yang baik.
sumber
Salah satu kesulitan saat menulis tes unit adalah Anda menulis kode, dan itu sendiri berpotensi rawan kesalahan. Ada juga kemungkinan bahwa Anda mungkin akhirnya perlu mengubah tes Anda nanti sebagai hasil dari upaya refactoring saat Anda menulis kode implementasi Anda. Dengan TDD, ini berarti Anda berpotensi berakhir sedikit terbawa dengan pengujian Anda dan menemukan diri Anda perlu menulis ulang banyak kode tes yang pada dasarnya "belum diuji" saat implementasi Anda matang selama proyek berlangsung. Salah satu cara untuk menghindari masalah semacam ini adalah dengan hanya fokus melakukan satu hal pada satu waktu. Ini memastikan Anda meminimalkan dampak dari setiap perubahan pada tes Anda.
Tentu saja, ini sebagian besar akan tergantung pada bagaimana Anda menulis kode pengujian Anda. Apakah Anda menulis tes unit untuk setiap metode individu, atau Anda menulis tes yang berfokus pada fitur / persyaratan / perilaku? Pendekatan lain bisa menggunakan pendekatan Behavior Driven dengan kerangka kerja yang sesuai, dan fokus pada tes menulis seolah-olah mereka spesifikasi. Ini berarti mengadopsi metode BDD, atau mengadaptasi pengujian BDD jika Anda ingin tetap menggunakan TDD secara lebih formal. Atau Anda mungkin tetap berpegang sepenuhnya pada paradigma TDD, namun mengubah cara Anda menulis tes sehingga alih-alih berfokus sepenuhnya pada metode pengujian secara individual, Anda menguji perilaku secara lebih umum sebagai sarana untuk memenuhi spesifikasi fitur persyaratan yang Anda laksanakan secara spesifik.
Terlepas dari pendekatan spesifik yang Anda ambil, dalam semua kasus yang saya jelaskan di atas Anda menggunakan pendekatan uji-pertama, jadi meskipun mungkin tergoda untuk hanya mengunduh otak Anda ke dalam ruang uji yang indah, Anda juga ingin melawan godaan untuk melakukan lebih dari itu mutlak diperlukan. Setiap kali saya akan memulai test suite baru saya mulai mengulangi YAGNI untuk diri saya sendiri, dan kadang-kadang bahkan memasukkannya ke dalam komentar dalam kode saya untuk mengingatkan saya untuk tetap fokus pada apa yang segera penting, dan hanya melakukan minimum yang diperlukan untuk memuaskan persyaratan fitur yang akan saya implementasikan. Menempel pada Red-Green-Refactor membantu memastikan bahwa Anda akan melakukan ini.
sumber
Saya pikir dengan melakukan ini, Anda kehilangan proses TDD. Dengan hanya menulis semua tes Anda di awal, Anda tidak benar-benar melalui proses pengembangan menggunakan TDD. Anda hanya menebak-nebak tes mana yang akan Anda butuhkan. Ini akan menjadi serangkaian tes yang sangat berbeda dari yang Anda akhirnya tulis jika Anda melakukannya satu per satu saat Anda mengembangkan kode Anda. (Kecuali jika program Anda bersifat sepele.)
sumber
Saya "menulis" semua tes yang dapat saya pikirkan di depan sambil "brainstorming", namun saya menulis setiap tes sebagai satu-satunya komentar yang menggambarkan tes tersebut.
Saya kemudian mengonversi satu tes ke kode dan melakukan pekerjaan sehingga akan mengkompilasi dan lulus . Seringkali saya memutuskan bahwa saya tidak memerlukan semua tes yang saya pikir saya lakukan, atau saya perlu tes yang berbeda, informasi ini hanya berasal dari penulisan kode untuk membuat tes lulus.
Masalahnya adalah Anda tidak dapat menulis tes dalam kode sampai Anda telah membuat metode dan kelas tes itu karena jika tidak, Anda hanya akan mendapatkan banyak kesalahan kompiler yang membuat Anda mengerjakan satu tes pada satu waktu.
Sekarang jika Anda menggunakan sistem seperti aliran spek ketika tes ditulis dalam "Bahasa Inggris" Anda mungkin ingin agar pelanggan menyetujui serangkaian tes saat Anda punya waktu, daripada hanya membuat tes tunggal.
sumber
Gagasan di balik TDD adalah iterasi cepat.
Jika Anda memiliki petak besar tes yang harus ditulis sebelum Anda harus menulis kode Anda, sulit untuk iteratif memperbaiki kode Anda.
Tanpa refactoring kode mudah Anda kehilangan banyak manfaat TDD.
sumber
Dalam pengalaman (terbatas) saya dengan TDD, saya dapat memberi tahu Anda bahwa setiap kali saya melanggar disiplin menulis satu tes pada suatu waktu, segalanya menjadi buruk. Ini jebakan yang mudah untuk dijebak. "Oh, metode itu sepele," pikirmu sendiri, "jadi aku akan menghapus dua tes terkait lainnya dan terus bergerak." Nah, coba tebak? Tidak ada yang sepele seperti yang terlihat. Setiap kali saya jatuh ke dalam perangkap ini, saya akhirnya men-debug sesuatu yang saya pikir mudah, tetapi ternyata memiliki kasus sudut aneh. Dan karena saya terus menulis beberapa tes sekaligus, itu banyak pekerjaan untuk melacak di mana bug itu.
Jika Anda membutuhkan kumpulan informasi, Anda memiliki banyak opsi:
Perhatikan bahwa tidak ada dalam daftar ini adalah kompiler. :-)
sumber
Anda berasumsi bahwa Anda tahu seperti apa kode Anda sebelum Anda menulisnya. TDD / BDD adalah proses desain / penemuan sebanyak proses QA. Untuk fitur yang diberikan Anda menulis tes paling sederhana yang akan memverifikasi bahwa fitur tersebut puas (kadang-kadang ini mungkin memerlukan beberapa karena kompleksitas fitur). Tes pertama yang Anda tulis dimuat dengan asumsi seperti apa kode kerja itu nantinya. Jika Anda menulis seluruh rangkaian pengujian sebelum menulis baris kode pertama untuk mendukungnya, Anda membuat litani asumsi yang tidak diverifikasi. Sebagai gantinya, tulis satu asumsi dan verifikasi. Kemudian tulis selanjutnya. Dalam proses memverifikasi asumsi berikutnya, Anda mungkin saja mematahkan asumsi sebelumnya sehingga Anda harus kembali dan mengubah asumsi pertama untuk mencocokkan kenyataan atau mengubah realitas sehingga asumsi pertama masih berlaku.
Pikirkan setiap unit tes yang Anda tulis sebagai teori dalam buku catatan ilmiah. Ketika Anda mengisi buku catatan itu, Anda membuktikan teori Anda dan membentuk yang baru. Terkadang membuktikan teori baru membantah teori sebelumnya sehingga Anda harus memperbaikinya. Lebih mudah untuk membuktikan satu teori sekaligus daripada mencoba membuktikan katakan 20 sekaligus.
sumber
TDD adalah pendekatan yang sangat iteratif, yang (dalam pengalaman saya) lebih cocok dengan cara pembangunan dunia nyata. Biasanya implementasi saya terbentuk secara bertahap selama proses ini, dan setiap langkah dapat membawa pertanyaan, wawasan, dan ide untuk pengujian lebih lanjut. Ini sangat ideal untuk menjaga pikiran saya tetap fokus pada tugas yang sebenarnya, dan sangat efisien karena saya hanya perlu menyimpan beberapa hal dalam memori jangka pendek kapan saja. Ini pada gilirannya mengurangi kemungkinan kesalahan.
Ide Anda pada dasarnya adalah pendekatan Big Test Up Front, yang IMHO lebih sulit ditangani, dan mungkin menjadi lebih boros. Bagaimana jika Anda menyadari di tengah-tengah pekerjaan Anda bahwa pendekatan Anda tidak baik, API Anda cacat dan Anda harus memulai dari awal, atau menggunakan perpustakaan pihak ke-3? Kemudian banyak pekerjaan menulis tes Anda di depan menjadi usaha yang sia-sia.
Yang mengatakan, jika ini berhasil untuk Anda, baiklah. Saya dapat membayangkan bahwa jika Anda bekerja dari spesifikasi teknis tetap, terperinci, pada domain yang Anda alami dengan akrab, dan / atau pada tugas yang cukup kecil, Anda mungkin memiliki sebagian besar atau semua kasus uji yang diperlukan siap dan implementasi Anda jelas langsung dari permulaan. Maka mungkin masuk akal untuk memulai dengan menulis semua tes sekaligus. Jika pengalaman Anda adalah bahwa ini membuat Anda lebih produktif dalam jangka panjang, Anda tidak perlu terlalu khawatir tentang buku peraturan :-)
sumber
Selain memikirkan satu hal, satu paradigma TDD adalah menulis kode seminimal mungkin untuk lulus ujian. Ketika Anda menulis satu tes pada satu waktu, itu jauh lebih mudah untuk melihat jalan untuk menulis kode yang cukup untuk mendapatkan tes untuk lulus. Dengan serangkaian tes yang harus dilalui, Anda tidak perlu melihat kode dalam langkah-langkah kecil tetapi harus melakukan lompatan besar untuk membuat semuanya lulus sekaligus.
Sekarang jika Anda tidak membatasi diri untuk menulis kode untuk membuat semuanya lulus "dalam sekali jalan," melainkan menulis kode yang cukup untuk melewati satu tes pada suatu waktu, itu mungkin masih berfungsi. Anda harus memiliki lebih banyak disiplin untuk tidak hanya melanjutkan dan menulis lebih banyak kode daripada yang Anda butuhkan. Setelah Anda mulai dari jalur itu, Anda membiarkan diri Anda terbuka untuk menulis lebih banyak kode daripada tes yang dijelaskan, yang dapat diuji , setidaknya dalam arti bahwa itu tidak didorong oleh tes dan mungkin dalam arti bahwa itu tidak diperlukan (atau dilakukan) dengan tes apa pun.
Turun apa yang harus dilakukan metode ini, seperti komentar, cerita, spesifikasi fungsional, dll, sangat bisa diterima. Saya akan menunggu untuk menerjemahkan ini menjadi tes satu per satu.
Hal lain yang dapat Anda lewatkan dengan menulis tes sekaligus adalah proses berpikir dengan lulus ujian dapat mendorong Anda untuk memikirkan kasus uji lainnya. Tanpa bank tes yang ada, Anda perlu memikirkan kasus uji berikutnya dalam konteks tes kelulusan terakhir. Seperti yang saya katakan, memiliki ide bagus tentang apa yang seharusnya dilakukan metode ini sangat baik, tetapi berkali-kali saya menemukan diri saya menemukan kemungkinan-kemungkinan baru yang saya tidak anggap sebagai apriori, tetapi yang hanya terjadi dalam proses penulisan tes. Ada bahaya bahwa Anda mungkin melewatkan ini kecuali Anda secara khusus membiasakan diri memikirkan tes baru apa yang dapat saya tulis yang belum saya miliki.
sumber
Saya telah bekerja pada sebuah proyek di mana pengembang yang menulis tes (gagal) berbeda dari pengembang yang menerapkan kode yang diperlukan untuk membuatnya lulus dan saya menemukan itu benar-benar efektif.
Dalam hal ini, hanya tes yang terkait dengan iterasi saat ini yang ditulis satu kali. Jadi apa yang Anda sarankan sangat mungkin dalam skenario semacam itu.
sumber
sumber
Siklus Red-Green-Refactor adalah daftar periksa yang diperuntukkan bagi pengembang yang baru mengenal TDD. Saya akan mengatakan itu adalah ide yang baik untuk mengikuti daftar periksa ini sampai Anda tahu kapan harus mengikutinya dan kapan Anda bisa memecahkannya (yaitu, sampai tahu tidak harus menanyakan pertanyaan ini pada stackoverflow :)
Setelah melakukan TDD selama hampir satu dekade saya dapat memberitahu Anda bahwa saya sangat jarang, jika pernah, menulis banyak tes gagal sebelum saya menulis kode produksi.
sumber
Anda menggambarkan BDD, di mana beberapa pemangku kepentingan eksternal memiliki spesifikasi yang dapat dieksekusi. Ini mungkin bermanfaat jika ada spesifikasi di muka yang telah ditentukan sebelumnya (misalnya spesifikasi format, standar industri atau di mana programmer bukan pakar domain).
Pendekatan normal kemudian secara bertahap mencakup semakin banyak tes penerimaan, yang merupakan kemajuan yang terlihat oleh manajer proyek dan pelanggan.
Anda biasanya memiliki tes ini ditentukan dan dieksekusi dalam kerangka BDD seperti Mentimun, Kebugaran atau semacamnya.
Namun, ini bukan sesuatu yang Anda campur dengan unit test Anda, yang jauh lebih dekat dengan detail implementasi yang rumit dengan banyak kasus tepi terkait API, masalah inisialisasi dll sangat terfokus pada item yang sedang diuji , yang merupakan artefak implementasi .
Disiplin red-green-refactor memiliki banyak manfaat, dan satu-satunya keuntungan Anda dapat berharap dengan mengetikkannya di depan adalah untuk mencapai titik impas.
sumber
Satu tes sekaligus: keunggulan utama adalah fokus pada satu hal. Pikirkan desain kedalaman-pertama: Anda bisa lebih dalam dan tetap fokus dengan putaran umpan balik cepat. Anda mungkin melewatkan ruang lingkup seluruh masalah! Itulah saat refactoring (besar) ikut berperan. Tanpanya TDD tidak berfungsi.
Semua tes: analisis dan perancangan dapat mengungkapkan lebih banyak ruang lingkup masalah Anda. Pikirkan desain luas pertama. Anda menganalisis masalah dari sudut yang lebih banyak dan menambahkan masukan dari pengalaman. Secara inheren lebih sulit, tetapi dapat menghasilkan manfaat yang menarik - lebih sedikit refactoring - jika Anda melakukan 'cukup banyak saja'. Berhati-hatilah, mudah untuk dianalisa secara berlebihan dan benar-benar meleset!
Saya merasa sulit untuk secara umum merekomendasikan untuk memilih satu atau yang lain, karena banyak faktor: pengalaman (terutama dengan masalah yang sama), pengetahuan dan keterampilan domain, keramahan kode untuk refactoring, kompleksitas masalah ...
Saya kira jika kita fokus lebih sempit ke aplikasi bisnis biasa maka TDD dengan pendekatan coba-coba & kesalahan paling cepat biasanya akan menang dalam hal efektivitas.
sumber
Dengan asumsi bahwa kerangka pengujian Anda mendukungnya, apa yang saya sarankan adalah alih-alih mengimplementasikan tes yang ingin Anda braindump, alih-alih tulis tes pending deskriptif yang nantinya akan Anda implementasikan. Misalnya, jika API Anda harus melakukan foo dan bar tetapi tidak biz, cukup tambahkan kode berikut (contoh ini di rspec) untuk suite pengujian Anda, lalu serang mereka satu per satu. Anda menurunkan pikiran Anda dengan cepat dan dapat mengatasi semua masalah Anda satu per satu. Ketika semua tes lulus Anda akan tahu kapan Anda telah mengatasi semua masalah yang Anda miliki selama braindump Anda.
sumber