Ada beberapa, tetapi keuntungannya jauh melebihi kerugiannya.
Ada kurva belajar yang curam.
Banyak pengembang tampaknya berharap bahwa mereka dapat efisien dengan pemrograman uji pertama sejak hari pertama. Sayangnya butuh banyak waktu untuk mendapatkan pengalaman dan program dengan kecepatan yang sama seperti sebelumnya. Anda tidak bisa menyiasatinya.
Untuk lebih spesifik, sangat mudah salah. Anda dapat dengan mudah (dengan niat yang sangat baik) akhirnya menulis sejumlah tes yang sulit untuk mempertahankan atau menguji hal-hal yang salah. Sulit untuk memberikan contoh di sini - masalah seperti ini hanya membutuhkan pengalaman untuk dipecahkan. Anda harus memiliki perasaan yang baik untuk memisahkan masalah dan merancang untuk diuji. Saran terbaik saya di sini adalah melakukan pemrograman pasangan dengan seseorang yang mengenal TDD dengan sangat baik.
Anda melakukan lebih banyak coding di muka.
Tes-pertama berarti Anda tidak dapat melewati tes (yang bagus) dan berarti Anda akan berakhir dengan menulis lebih banyak kode di muka. Ini berarti lebih banyak waktu. Sekali lagi, Anda tidak bisa menyiasatinya. Anda mendapatkan imbalan dengan kode yang lebih mudah dipelihara, diperluas, dan umumnya lebih sedikit bug, tetapi butuh waktu.
Bisa menjadi penjualan yang sulit bagi para manajer.
Manajer perangkat lunak pada umumnya hanya mementingkan waktu. Jika Anda beralih ke pemrograman pengujian pertama dan Anda tiba-tiba membutuhkan waktu 2 minggu untuk menyelesaikan fitur, bukan satu, mereka tidak akan menyukainya. Ini jelas merupakan pertempuran yang layak diperjuangkan dan banyak manajer yang cukup tercerahkan untuk mendapatkannya, tetapi ini bisa menjadi penjualan yang sulit.
Bisa menjadi penjualan yang sulit untuk sesama pengembang.
Karena ada kurva belajar yang curam, tidak semua pengembang menyukai pemrograman uji-pertama. Bahkan, saya kira sebagian besar pengembang tidak menyukainya pada awalnya. Anda dapat melakukan hal-hal seperti pemrograman pasangan untuk membantu mereka mencapai kecepatan, tetapi itu bisa menjadi penjualan yang sulit.
Pada akhirnya, keuntungannya melebihi kerugiannya, tetapi itu tidak membantu jika Anda mengabaikan kerugiannya. Mengetahui apa yang Anda hadapi sejak awal membantu Anda menegosiasikan beberapa kelemahan, jika tidak semua.
Tes-pertama mengasumsikan Anda menulis kode yaitu:
Jika proyek Anda tidak memenuhi persyaratan tersebut, Anda akan mengalami kesulitan. Promotor TDD tidak memiliki jawaban yang baik untuk yang lain ini untuk menyarankan agar Anda mendesain ulang produk Anda agar lebih sesuai dengan garis-garis itu. Ada situasi di mana itu tidak mungkin atau tidak diinginkan.
Dalam praktiknya, saya juga bisa mengalami masalah besar dengan orang-orang yang berpikir tes pertama benar-benar membuktikan apa pun tentang fungsi program yang benar. Dalam banyak kasus ini tidak benar, tetapi bahkan dalam kasus di mana itu benar itu jauh dari gambaran lengkap tentang kebenaran. Orang melihat ratusan tes yang lulus dan menganggap aman untuk menguji kurang karena sebelum TDD mereka hanya melakukan beberapa ratus kasus uji. Dalam pengalaman saya, TDD berarti bahwa Anda perlu memiliki lebih banyak tes integrasi karena pengembang juga akan memiliki keamanan palsu dan rasa sakit karena mengubah semua tes untuk melakukan redactor besar dapat membuat pengembang membuat pekerjaan yang menarik di sekitarnya.
Contoh:
Contoh terbaik pribadi saya adalah ketika menulis kode keamanan untuk asp.net. Jika mereka dimaksudkan untuk berjalan dalam lingkungan yang tidak bersahabat dari konfigurasi mesin, mereka dihadang, ditandatangani dan disegel, dan karena mereka berlari melawan benda-benda dewa IIS, mereka sangat sulit untuk diejek dengan sangat benar. Tambahkan beberapa kendala untuk kinerja dan penggunaan memori dan Anda dengan cepat kehilangan fleksibilitas untuk menggunakan objek placeholder di area yang tersisa.
Segala jenis pengontrol mikro atau kode lingkungan sumber daya rendah lainnya tidak mungkin dilakukan untuk benar-benar mendesain gaya OO karena abstraksi tidak dioptimalkan dan Anda memiliki batas sumber daya yang rendah. Hal yang sama dapat dikatakan untuk rutinitas kinerja tinggi dalam banyak kasus juga.
sumber
Kelemahan terbesar yang saya lihat bukan dengan TDD itu sendiri tetapi dengan praktisi. Mereka mengambil pendekatan dogmatis dan fanatik di mana semuanya harus diuji . Terkadang (berkali-kali itu), itu tidak perlu. Juga, ini mungkin tidak praktis (mis. Memperkenalkan organisasi ke TDD.)
Seorang insinyur yang baik menemukan pengorbanan dan menerapkan keseimbangan yang tepat kapan / di mana / bagaimana menerapkan tes-pertama. Juga, jika Anda mendapati diri Anda terus-menerus menghabiskan lebih banyak waktu mengembangkan tes daripada kode yang sebenarnya (dengan faktor 2-3 atau lebih), Anda dalam masalah.
Dengan kata lain, bersikap pragmatis dan masuk akal dengan TDD (atau apa pun dalam pengembangan perangkat lunak dalam hal ini.)
sumber
Saya mulai melakukan TDD pada awal Agustus 2009 dan meyakinkan seluruh perusahaan saya untuk beralih ke hal itu pada bulan September / Oktober 2009. Saat ini, seluruh tim dev sepenuhnya dikonversi, dan melakukan kode yang belum diuji ke repo dianggap sebagai Hal Buruk dan dibuang. Ini telah bekerja dengan baik bagi kami, dan saya tidak bisa membayangkan beralih kembali ke pengkodean koboi.
Namun, ada dua masalah yang cukup mencolok.
Test suite harus dipertahankan
Ketika Anda serius tentang TDD, Anda akan berakhir dengan menulis banyak tes. Selain itu, perlu beberapa waktu dan pengalaman untuk menyadari apa granularity yang tepat dari tes (overdoing hampir sama buruknya dengan underdoing). Tes-tes ini juga merupakan kode , dan mereka rentan terhadap bitrot. Ini berarti Anda harus mempertahankannya seperti yang lainnya: perbarui ketika Anda memutakhirkan pustaka yang menjadi andalannya, refactor dari waktu ke waktu ... Saat Anda membuat perubahan besar pada kode Anda, banyak tes tiba-tiba akan menjadi ketinggalan zaman atau bahkan jelas salah. Jika Anda beruntung, Anda bisa menghapusnya, tetapi sering kali Anda akan mengekstraksi bit yang berguna dan mengadaptasinya ke arsitektur baru.
Abstraksi pengujian bocor dari waktu ke waktu
Kami menggunakan Django, yang memiliki kerangka pengujian yang cukup bagus. Namun, terkadang ia membuat asumsi yang sedikit bertentangan dengan kenyataan. Misalnya, beberapa middleware dapat merusak tes. Atau, beberapa tes membuat asumsi tentang backend caching. Juga, jika Anda menggunakan "nyata" db (bukan SQLite3), maka mempersiapkan db untuk tes akan memakan banyak waktu. Tentu, Anda dapat (dan harus) menggunakan SQLite3 dan db dalam memori untuk tes yang Anda lakukan secara lokal, tetapi beberapa kode hanya akan berperilaku berbeda tergantung pada database yang Anda gunakan. Menyiapkan server integrasi berkelanjutan yang berjalan dalam pengaturan realistis adalah suatu keharusan.
(Beberapa orang akan memberi tahu Anda bahwa Anda harus mengejek semua hal seperti database, atau tes Anda tidak "murni," tetapi itu hanya berbicara tentang ideologi. Jika Anda membuat kesalahan dalam kode ejekan Anda (dan percayalah, Anda akan), testuite Anda akan menjadi tidak berharga.)
Ini semua mengatakan, masalah yang saya jelaskan mulai terlihat hanya ketika Anda cukup maju dengan TDD ... Ketika Anda baru mulai dengan TDD (atau mengerjakan proyek yang lebih kecil) tes refactoring tidak akan menjadi masalah.
sumber
Bagi saya ada beberapa masalah psikologis yang mendalam dengan tes setiap kali saya mencoba menerapkannya secara luas, seperti pada TDD: jika ada, saya kode sembarangan karena saya percaya bahwa tes akan menangkap masalah. Tetapi jika tidak ada tes untuk menyediakan jaring pengaman, saya kode dengan hati-hati, dan hasilnya selalu lebih baik daripada dengan tes.
Mungkin hanya aku. Tetapi saya juga pernah membaca di suatu tempat bahwa mobil dengan semua jenis lonceng & peluit cenderung lebih sering menabrak (karena pengemudi tahu bahwa fitur keselamatan ada di sana), jadi mungkin ini sesuatu yang perlu diketahui; TDD dapat tidak kompatibel dengan beberapa individu.
sumber
Satu situasi di mana tes pertama benar-benar menghalangi saya adalah ketika saya ingin dengan cepat mencoba beberapa ide dan melihat apakah itu bisa bekerja sebelum saya menulis implementasi yang tepat.
Pendekatan saya biasanya:
Terkadang saya tidak sampai ke langkah 2.
Dalam hal ini, menggunakan TDD ternyata memiliki lebih banyak kerugian daripada keuntungan bagi saya:
Jadi, ketika saya harus menjelajahi beberapa ide baru, saya tidak menggunakan TDD dan hanya memperkenalkan unit test ketika saya merasa kode baru tersebut mencapai suatu tempat.
sumber
Kekurangan atau Biaya TDD
Catatan: Ada berbagai jenis TDD. Terlepas dari unit, BDD, ATDD, atau varian lain banyak dari kesulitan tetap ada
Efek samping
Baik itu mengejek, perlengkapan, atau tes fungsional, ketergantungan pada kondisi eksternal atau sistem sering kali menjadi sumber paling rumit dalam pengujian, kebingungan dalam cara menguji, dan risiko terbesar jika salah melakukannya. Beberapa masalah yang saya lihat:
Anda harus mengubah pendekatan Anda terhadap pengkodean, untuk beberapa hal itu akan menjadi perubahan drastis.
Kode orang berbeda dengan cara yang sangat berbeda. Di TDD Anda harus mulai dengan tes yang menegaskan perilaku tertentu, dan kemudian menerapkannya sehingga tes berlalu. Saya telah melihat dan merupakan seorang programmer yang pemrogramannya tidak kondusif untuk TDD. Butuh waktu sekitar 2 bulan ketika saya awalnya mulai terbiasa mengubah pendekatan pengembangan saya.
Butuh waktu untuk memahami apa yang Anda pedulikan tentang pengujian dan apa yang tidak Anda pedulikan tentang pengujian.
Setiap tim harus membuat keputusan eksplisit tentang di mana mereka ingin menarik garis dalam pengujian. Hal-hal apa yang mereka nilai yang ingin mereka uji, dan apa yang tidak. Seringkali proses yang menyakitkan mempelajari bagaimana menulis tes yang baik, dan apa yang sebenarnya Anda pedulikan tentang pengujian. Sementara itu kode akan terus dalam keadaan fluks sampai ada konsistensi dalam gaya dan pendekatan.
Unit Test spesifik: refaktor besar
Refactor besar atau mendasar dari basis kode yang signifikan dengan puluhan ribu unit test akan menghasilkan biaya yang sangat besar untuk memperbarui semua tes. Ini akan sering terwujud dalam pushback terhadap melakukan refactor bahkan jika itu adalah hal yang benar untuk dilakukan hanya karena biaya yang terkait dengan melakukannya.
sumber
Analogi saya adalah penghalang di jalur Scalextric. Jika Anda memakainya, Anda menjadi kurang berhati-hati.
Orang-orang juga mendapatkan sedikit ruang cadetish tentang tes mereka - karena mereka berjalan dengan baik, mereka percaya kode tersebut sepenuhnya diuji sedangkan itu hanya awal dari proses pengujian.
Dalam pikiran saya TDD adalah batu loncatan ke BDD. Rakit tes yang berjalan tidak benar-benar membantu mendukung pengembang tanpa mengetahui apa yang dilakukan tes. Dengan BDD, output tes dalam bahasa Inggris yang mendokumentasikan pengujian dan dengan demikian membangun pemahaman sistem.
sumber
Manfaat TDD adalah memaksa Anda untuk menjaga kode Anda terhadap orang-orang yang tidak memahaminya. Ya, ini sering termasuk diri Anda sendiri. Tapi, apa yang terjadi ketika kode tidak layak dijaga? Ada banyak kode yang seharusnya tidak ada di sana! Jadi masalah dengan TDD adalah ketika datang ke pengembang yang menulis kode buruk. TDD mungkin tidak akan membantu mereka menulis kode yang baik, kemungkinan besar mereka akan menulis tes yang mengerikan juga. Jadi dalam kasus mereka TDD hanya akan menambah kekacauan; tes yang ditulis dengan buruk dan / atau redundan tidak lebih menyenangkan daripada bentuk kode buruk lainnya.
sumber