Orang mengatakan bahwa "berbicara tentang TDD tidak berhasil, jika Anda ingin meyakinkan seseorang untuk TDD, tunjukkan hasil". Namun, saya sudah mendapatkan hasil yang bagus tanpa TDD. Menunjukkan kepada saya bahwa orang yang menggunakan TDD mendapatkan hasil yang baik tidak akan meyakinkan, saya ingin melihat bahwa orang yang menulis TDD dan bukan-TDD mendapatkan hasil yang lebih baik dengan TDD.
Terlepas dari semua ini, saya tertarik untuk mencoba TDD. Namun saya tidak yakin saya akan mendapatkan apa pun dari ini. Jika terbukti bermanfaat, saya akan mencoba mendorongnya ke seluruh tim saya.
Pertanyaan utama saya adalah ini: Apakah TDD melayani tujuan apa pun untuk kode, jika saya sudah dapat membuktikan kebenaran kode?
Jelas, tidak ada yang peluru. Bukti Anda mungkin salah karena Anda melewatkan detail, dan pengujian Anda mungkin gagal menemukan bug yang gagal Anda uji. Pada akhirnya, kita manusia, tidak ada yang bisa membuat kode bebas bug 100% selamanya. Kami hanya bisa berusaha sedekat mungkin.
Namun, apakah TDD benar-benar menghemat waktu pada kode yang kebenarannya telah terbukti? yaitu kode yang, di mesin negara di mana kode beroperasi, semua status yang mungkin valid dan rentangnya diakui oleh pengembang, semua diperhitungkan, dan kode tersebut dirancang dalam pemeriksaan kesalahan gaya daftar putih yang melewati setiap pengecualian untuk penangan atas untuk memastikan tidak ada kebocoran yang tidak terduga -> tanpa keduanya menampilkan pesan (sesuai alasan-) kepada klien dan mengirim pemberitahuan log ke admin.
Jawaban dengan contoh nyata akan lebih baik.
Beberapa klarifikasi:
Pertanyaan ini bukan tentang apakah Anda dapat membuktikan kebenaran kode atau tidak. Mari kita asumsikan secara default bahwa tidak semua kode dapat dibuktikan benar dalam jangka waktu yang masuk akal, tetapi beberapa kode dapat. Misalnya, sangat mudah untuk membuktikan kebenaran modul FizzBuzz. Tidak mudah untuk layanan sinkronisasi data berbasis cloud.
Dalam batasan ini, pertanyaan diajukan sebagai berikut: Mulai dengan asumsi bahwa basis kode dibagi menjadi 2 bagian: [I] bagian yang telah terbukti benar [II] bagian yang belum terbukti benar, tetapi diuji secara manual untuk bekerja.
Saya ingin menerapkan praktik TDD ke basis kode ini yang tidak memilikinya hingga sekarang. Pertanyaannya adalah sebagai berikut: haruskah TDD diterapkan ke setiap modul tunggal, atau apakah cukup untuk menerapkannya hanya pada modul yang tidak terbukti benar?
"Terbukti benar" berarti Anda dapat mempertimbangkan modul ini sepenuhnya fungsional-gaya, yaitu, ia tidak bergantung pada keadaan global atau luar di luar itu sendiri, dan sepenuhnya memiliki API sendiri untuk I / O yang harus diikuti oleh modul lain yang berinteraksi dengannya. . Tidak mungkin untuk "memecah modul ini" dengan mengubah kode di luar modul, paling buruk Anda dapat menyalahgunakannya dan mendapatkan pesan kesalahan yang diformat dikembalikan kepada Anda.
Jelas, setiap aturan memiliki pengecualian, bug penyusun dalam versi penyusun baru dapat memperkenalkan bug pada modul ini, tetapi bug yang sama dapat diperkenalkan ke pengujian yang mengujinya dan menghasilkan rasa aman yang salah dari pengujian yang tidak lagi berfungsi sebagaimana dimaksud. Intinya adalah bahwa tes bukan solusi ajaib, mereka adalah lapisan perlindungan lain, dan pertanyaan ini membahas masalah apakah lapisan perlindungan ini sepadan dengan usaha dalam kasus spesifik modul yang terbukti benar (asumsikan bahwa memang).
Jawaban:
Iya.
Bukti baik-baik saja ketika mereka tersedia, tetapi bahkan pada saat terbaik mereka hanya membuktikan bahwa sedikit kode akan bekerja seperti yang diharapkan (untuk semua input? Akuntansi untuk gangguan di tengah operasi apa pun? Bagaimana dengan kehabisan memori? ? kegagalan disk? kegagalan jaringan?)
Apa yang terjadi ketika itu berubah?
Tes sangat bagus karena berfungsi sebagai kontrak tersirat tentang apa yang harus dilakukan kode. Mereka menyediakan beberapa perancah sehingga magang baru Anda dapat masuk dan melakukan perubahan dengan tingkat kepercayaan tertentu. Semua melalui hasil yang cepat dan jelas: lulus atau gagal.
Dan sejujurnya, saya bisa melatih magang untuk menulis tes unit yang layak dalam beberapa bulan. Saya ragu bahwa siapa pun di tim saya (termasuk saya) dapat membuat bukti yang menjamin sesuatu yang berarti untuk kode non-sepele; apalagi melakukannya dengan cepat dan akurat.
sumber
For large & rapidly changing projects
semakin rentan untuk berubah semakin penting adalah tes, karena kode perubahan memiliki lebih banyak peluang untuk gagal karena bug baru atau perilaku tak terduga, daripada kode yang nyaris tidak berubah. Ini masalah probabilitas. Bahkan jika itu tidak sering berubah, setelah beberapa saat pengetahuan yang diperoleh selama pengembangan bisa hilang atau terlupakan. Tes juga merupakan pengetahuan yang terwujud, yang dapat mengurangi, secara signifikan, kurva pembelajaran. Apakah pengujian kode memakan waktu? Iya. Apakah itu membuat proyek lebih mahal? Tidak, dalam jangka panjang membuatnya lebih murah .Kami tidak tahu. Kami tidak dapat menjawab pertanyaan Anda.
Sementara Anda menghabiskan banyak waktu untuk menjelaskan proses yang Anda miliki sekarang tampaknya bekerja untuk kepuasan semua orang, Anda memberi tahu kami hanya sepotong kecil dari apa yang sebenarnya terjadi.
Dari pengalaman saya, apa yang Anda gambarkan adalah kelangkaan yang ekstrem dan saya ragu bahwa sebenarnya proses dan pendekatan Anda terhadap pengkodean yang sebenarnya menyebabkan jumlah bug yang rendah dalam aplikasi Anda. Mungkin ada banyak faktor lain yang memengaruhi aplikasi Anda dan Anda tidak memberi tahu kami tentang faktor-faktor itu.
Jadi kami tidak tahu, dalam menghadapi tidak mengetahui lingkungan pengembangan dan budaya Anda, apakah TDD akan membantu Anda atau tidak. Dan kita bisa menghabiskan waktu berhari-hari untuk berdiskusi dan berdebat tentang hal itu.
Hanya ada satu rekomendasi yang dapat kami berikan kepada Anda: cobalah. Percobaan. Pelajari itu. Saya tahu Anda berusaha menghabiskan paling sedikit upaya untuk memutuskan, tetapi itu tidak mungkin. Jika Anda benar-benar ingin tahu apakah TDD akan berfungsi dalam konteks Anda, satu-satunya cara untuk mengetahuinya adalah dengan benar-benar melakukan TDD. Jika Anda benar-benar mempelajarinya dan menerapkannya pada aplikasi Anda, Anda dapat membandingkannya dengan proses non-TDD Anda. Mungkin TDD sebenarnya memiliki kelebihan dan Anda memutuskan untuk menyimpannya. Atau bisa keluar bahwa TDD tidak membawa sesuatu yang baru dan hanya memperlambat Anda. Dalam hal ini, Anda dapat kembali ke proses sebelumnya.
sumber
Tujuan utama dari pengujian (unit) adalah menjaga kode, memastikan kode tidak pecah tanpa disadari karena perubahan di kemudian hari. Ketika kode pertama kali ditulis, itu akan mendapatkan banyak perhatian dan akan diteliti. Dan Anda mungkin memiliki beberapa sistem superior untuk itu.
Enam bulan kemudian, ketika orang lain mengerjakan sesuatu yang tampaknya tidak berhubungan, itu mungkin rusak dan super-duper-code-correctver-prover Anda tidak akan menyadarinya. Tes otomatis akan.
sumber
Ini adalah cara tersulit untuk mempelajari TDD. Semakin lama Anda menguji, semakin banyak biayanya untuk menulis tes dan semakin sedikit Anda keluar dari menulisnya.
Saya tidak mengatakan tidak mungkin untuk retrofit tes ke basis kode yang ada. Saya mengatakan hal itu tidak akan membuat siapa pun menjadi penganut TDD. Ini kerja keras.
Sebenarnya lebih baik berlatih TDD pertama kali pada sesuatu yang baru dan di rumah. Dengan begitu Anda belajar ritme yang sebenarnya. Lakukan ini dengan benar dan Anda akan ketagihan.
Itu adalah pemikiran struktural. Anda seharusnya tidak mengatakan hal-hal seperti menguji setiap fungsi, atau kelas, atau modul. Batas-batas itu tidak penting untuk pengujian dan mereka harus dapat berubah pula. TDD adalah tentang membangun kebutuhan perilaku yang dapat diuji dan tidak peduli bagaimana itu terpenuhi. Kalau bukan kita tidak bisa refactor.
Cukup menerapkannya di tempat Anda menemukan kebutuhannya. Saya akan mulai dengan kode baru. Anda akan mendapatkan jauh lebih banyak dari pengujian awal daripada dari terlambat. Jangan lakukan ini di tempat kerja sampai Anda sudah cukup berlatih untuk menguasainya di rumah.
Ketika Anda telah menunjukkan TDD efektif dengan kode baru di tempat kerja dan merasa cukup percaya diri untuk mengambil kode lama saya akan mulai dengan kode yang terbukti. Alasannya adalah karena Anda akan dapat langsung melihat jika tes yang Anda tulis mengambil kode ke arah yang baik.
Tes tidak hanya membuktikan kebenaran. Mereka menunjukkan niat. Mereka menunjukkan apa yang dibutuhkan. Mereka menunjukkan jalan untuk berubah. Tes yang bagus mengatakan ada beberapa cara untuk menulis kode ini dan mendapatkan yang Anda inginkan. Mereka membantu pembuat kode baru melihat apa yang dapat mereka lakukan tanpa merusak segalanya.
Hanya sekali Anda memilikinya turun Anda harus berjalan ke kode yang belum terbukti.
Sebuah peringatan terhadap orang-orang fanatik: Anda terdengar seperti Anda telah mencapai kesuksesan dan karena itu tidak akan mungkin melompat lebih dulu. Tetapi orang-orang lain yang ingin membuktikan diri mereka tidak akan begitu tertutup TDD bisa berlebihan. Sangat luar biasa mudah untuk membuat serangkaian pengujian yang benar-benar merugikan refactoring karena mereka mengunci hal-hal yang sepele dan tidak berarti. Bagaimana ini bisa terjadi? Karena orang yang ingin memamerkan tes hanya menulis tes dan tidak pernah refactor. Larutan? Buat mereka refactor. Buat mereka berurusan dengan perubahan fitur. Lebih cepat lebih baik. Itu akan menunjukkan kepada Anda tes yang tidak berguna dengan cepat. Anda membuktikan fleksibilitas dengan melenturkan.
Peringatan terhadap kategorisasi struktural: Beberapa orang akan bersikeras bahwa kelas adalah unit. Beberapa akan menyebut tes apa pun dengan dua kelas sebagai tes integrasi. Beberapa akan bersikeras bahwa Anda tidak dapat melewati batas x dan menyebutnya sebagai unit test. Daripada peduli tentang semua itu, saya menyarankan Anda untuk peduli tentang bagaimana tes Anda berperilaku. Bisakah itu berjalan dalam sepersekian detik? Apakah bisa dijalankan secara paralel dengan tes lain (efek samping gratis)? Bisakah itu dijalankan tanpa memulai atau mengedit hal lain untuk memenuhi dependensi dan prasyarat? Saya menempatkan pertimbangan ini di depan jika berbicara dengan DB, sistem file, atau jaringan. Mengapa? Karena tiga yang terakhir ini hanya masalah karena mereka menyebabkan masalah lain. Kelompokkan tes Anda bersama-sama berdasarkan cara Anda mengharapkannya berperilaku. Bukan batas yang kebetulan mereka lewati. Maka Anda tahu apa yang dapat Anda harapkan dari setiap test suite.
Pertanyaan itu sudah ada jawabannya di sini .
sumber
Pengembangan Test Driven lebih tentang prototyping dan brainstorming API, daripada pengujian. Tes yang dibuat seringkali berkualitas buruk dan akhirnya harus dibuang. Keuntungan utama TDD adalah menentukan bagaimana API akan digunakan, sebelum menulis implementasi API. Keuntungan ini juga dapat diperoleh dengan cara lain, misalnya dengan menulis dokumentasi API sebelum implementasi.
Bukti kebenaran selalu lebih berharga daripada tes. Tes tidak membuktikan apa pun. Namun, untuk menggunakan bukti kebenaran secara produktif, akan membantu untuk memiliki pemeriksa bukti otomatis, dan Anda perlu bekerja menggunakan beberapa jenis kontrak (desain berdasarkan kontrak atau desain berbasis kontrak).
Di masa lalu, ketika bekerja pada bagian kode yang kritis, saya akan mencoba bukti kebenaran manual. Bahkan bukti informal lebih berharga daripada tes otomatis. Tetapi Anda masih membutuhkan tes, kecuali jika Anda dapat mengotomatiskan bukti Anda, karena orang-orang akan merusak kode Anda di masa depan.
Tes otomatis tidak menyiratkan TDD.
sumber
String getSomeValue()
sini sehingga kita bisa mengujinya" ketika itu tidak masuk akal untuk desain keseluruhan. Tentu, Anda bisa menghapus fungsi itu nanti, tetapi, dalam pengalaman saya, itu jarang terjadi.A) Anda membaca kode dan meyakinkan diri sendiri bahwa itu benar tidak jauh dari membuktikan itu benar. Kalau tidak mengapa menulis tes sama sekali?
B) Ketika Anda mengubah kode Anda ingin menjalankan tes yang menunjukkan kode masih benar atau tidak.
sumber
Saya akan memperingatkan dengan mengatakan bahwa sekali Anda terbiasa menggunakan TDD secara efektif, itu akan menghemat waktu Anda di akhir permainan. Dibutuhkan latihan untuk mempelajari cara menggunakan TDD secara efektif, dan itu tidak membantu ketika Anda berada di bawah krisis waktu. Ketika belajar bagaimana memanfaatkannya dengan baik, saya sarankan memulai proyek pribadi di mana Anda memiliki lebih banyak waktu luang dan lebih sedikit tekanan jadwal.
Anda akan menemukan bahwa kemajuan awal Anda lebih lambat saat Anda bereksperimen lebih banyak dan membuat API Anda ditulis. Seiring waktu, kemajuan Anda akan lebih cepat karena tes baru Anda mulai berlalu tanpa mengubah kode, dan Anda memiliki basis yang sangat stabil untuk membangun. Pada akhir permainan, kode yang tidak dibangun menggunakan TDD mengharuskan Anda menghabiskan lebih banyak waktu dalam debugger saat Anda mencoba mencari tahu apa yang salah dari yang seharusnya diperlukan. Anda juga menghadapi risiko lebih besar untuk melanggar sesuatu yang dulu bekerja dengan perubahan baru. Menilai efektivitas TDD vs tidak menggunakannya dengan total waktu hingga selesai.
Konon, TDD bukan satu-satunya game di kota. Anda dapat menggunakan BDD yang menggunakan cara standar untuk mengekspresikan perilaku aplikasi tumpukan penuh, dan menilai kebenaran API dari sana.
Seluruh argumen Anda bergantung pada "membuktikan kebenaran kode", jadi Anda perlu sesuatu yang mendefinisikan kebenaran kode. Jika Anda tidak menggunakan alat otomatis untuk mendefinisikan apa artinya "benar", maka definisi tersebut sangat subyektif. Jika definisi Anda yang benar didasarkan pada konsensus rekan-rekan Anda, itu dapat berubah pada hari tertentu. Definisi Anda yang benar perlu konkret dan dapat diverifikasi, yang juga berarti harus dapat dievaluasi oleh suatu alat. Mengapa tidak menggunakannya?
Kemenangan # 1 dari menggunakan pengujian otomatis apa pun, adalah Anda dapat memverifikasi kode Anda tetap benar bahkan ketika tambalan OS diterapkan dengan cepat dan efisien. Jalankan suite Anda untuk memastikan semuanya lewat, lalu terapkan tambalan dan jalankan suite lagi. Lebih baik lagi, jadikan ini bagian dari infrastruktur build otomatis Anda. Sekarang Anda dapat memverifikasi kode Anda tetap benar setelah menggabungkan kode dari beberapa pengembang.
Pengalaman saya menggunakan TDD telah membawa saya ke kesimpulan berikut:
Pengalaman saya menggunakan BDD telah membawa saya ke kesimpulan berikut:
Definisi Benar: Kode Anda mematuhi persyaratan. Ini paling baik diverifikasi dengan BDD, yang menyediakan sarana untuk mengekspresikan persyaratan tersebut dengan cara yang dapat dibaca manusia dan memverifikasinya pada waktu berjalan.
Saya tidak berbicara tentang kebenaran dalam hal bukti matematis, yang tidak mungkin. Dan saya lelah dengan argumen itu.
sumber