Pengalaman negatif TDD [ditutup]

95

Apa sisi negatif dari pengalaman TDD Anda? Apakah Anda menemukan langkah bayi (perbaikan paling sederhana untuk membuat tes hijau) mengganggu dan tidak berguna? Apakah Anda menemukan tes tidak-bernilai (ketika tes awalnya masuk akal tetapi dalam implementasi akhir memeriksa logika yang sama dengan tes lainnya) tetap penting? dll.

Pertanyaan di atas adalah tentang hal-hal yang saya merasa tidak nyaman selama pengalaman TDD saya. Jadi saya tertarik apakah pengembang lain memiliki perasaan yang sama dan apa yang mereka pikirkan tentang mereka.

Akan berterima kasih atas tautan ke artikel yang menggambarkan sisi negatif TDD (Google dipenuhi oleh artikel positif dan sering fanatik).

Idsa
sumber
10
Dugaan saya adalah bahwa Anda tidak akan mendengar banyak jawaban jujur ​​tentang pengalaman negatif orang, karena TDD masih dalam keadaan "pengadopsi awal" dan kebanyakan orang yang tertarik dan berkomitmen untuk mencobanya tidak cukup objektif untuk mengevaluasinya berdasarkan kemampuan relatifnya. Biasanya diperlukan beberapa tahun bagi industri untuk benar-benar membangun efek jangka panjang dari proses dan teknik baru, dan bahkan kemudian sulit untuk mendapatkan jawaban langsung karena kurangnya kontrol. Namun, pertanyaan yang bagus, dan semoga sukses mendapatkan jawaban yang bermanfaat!
Aaronaught
20
Apakah Anda kesulitan menemukan hal negatif di internet ?!
Eric Wilson
4
@ Pekerjaan (dan mungkin lainnya): jangan lupa dia bertanya tentang TDD, bukan pengujian unit. TDD! = Pengujian unit.
n1ckp
2
Saya tergoda untuk menjawab pertanyaan ini, tetapi saya tidak benar-benar ingin memulai karena itu akan memakan waktu setengah hari saya.
Rei Miyasaka
2
Ketika saya mendapati diri saya menghabiskan cukup waktu pada bug yang sepertinya saya bisa menghabiskan lebih sedikit waktu menulis tes untuk setiap hal yang saya tulis sebelum saya menulisnya, saya tidak akan mengadopsi test-first-everything-TDD. Sebagai gantinya saya akan menundukkan kepala karena malu dan mulai mencari karier baru. Bukan tentang bug yang Anda katakan? Desain? Iya. Itu dia. Tepat seperti itu. Dan Anda belum belajar apa-apa tentang desain yang kuat dengan memberikan diri Anda jaring pengaman dan lisensi untuk terus bekerja bodoh. Singkirkan IDE dan coba baca kode Anda jika Anda ingin menemukan masalah sebenarnya.
Erik Reppen

Jawaban:

95

Seperti semua yang ada di bawah spanduk "Agile", TDD adalah sesuatu yang terdengar bagus secara teori, tetapi dalam praktiknya tidak begitu jelas seberapa bagusnya (dan juga seperti kebanyakan hal "Agile", Anda diberitahu bahwa jika Anda tidak seperti itu, kamu salah melakukannya).

Definisi TDD tidak terukir di batu: orang-orang seperti Kent Beck menuntut tes non-kompilasi harus ditulis sebelum satu baris kode dan setiap baris kode harus ditulis untuk lulus tes gagal. Desain depan minimal dan semuanya didorongoleh tes. Itu tidak bekerja. Saya telah melihat aplikasi perusahaan besar yang dikembangkan menggunakan metodologi itu dan saya berharap itu adalah kode terburuk yang saya lihat dalam karir saya (tidak akan jauh; dan itu meskipun ada beberapa pengembang berbakat yang mengerjakannya). Dari apa yang saya lihat itu menghasilkan sejumlah besar tes dipikirkan dengan buruk yang terutama memvalidasi bahwa panggilan fungsi terjadi, bahwa pengecualian dilemparkan ketika variabel nol dan kerangka kerja mengejek mendapat latihan menyeluruh (whoop-de-whoop); kode produksi Anda akan sangat digabungkan ke tes ini dan mimpi refactoring yang konstan dan mudah tidak muncul - pada kenyataannya orang bahkan cenderung memperbaiki kode buruk karena semua tes itu akan rusak.

Sebaliknya saya pernah mendengar orang berpendapat bahwa TDD berarti merancang tes di muka pada tingkat tinggi sebagai bagian dari tahap perencanaan - di samping desain arsitektur. Tes ini dapat berubah selama pengembangan karena lebih banyak informasi tersedia, tetapi mereka telah dipertimbangkan dengan hati-hati dan menawarkan panduan yang baik tentang apa yang sebenarnya harus dilakukan kode. Bagi saya itu masuk akal.

user23157
sumber
7
+1 "merancang tes di muka pada tingkat tinggi sebagai bagian dari fase perencanaan - di samping desain arsitektur" Kedengarannya jauh lebih masuk akal bagi saya juga.
Steven Jeuris
11
@Aaronaught Agile bukan berarti tidak ada perencanaan, itu berarti hanya dalam perencanaan waktu .
Adam Jaskiewicz
25
@Adam Jaskiewicz: Saya suka hal "tidak ada perencanaan awal". Ayo, perencanaan dimuka menurut definisi . Jika Anda tidak merencanakan sebelumnya tetapi selama acara itu Anda tidak berencana sama sekali; Anda berimprovisasi. ;-)
CesarGon
34
@Adam - "Apakah orang benar-benar melompat langsung ke pengkodean pada hari pertama iterasi?" erm ya Itu pria "Agile". Tempat terakhir saya bekerja (dan dipecat dari karena tidak "Agile") mereka melakukan siklus rilis 3 bulan penuh tanpa pernah merencanakan satu baris kode atau melakukan satu halaman dokumentasi. Dan ya kodenya mengerikan dan ya peranti lunaknya lambat, kikuk dan buggy. Pada hari saya bergabung, saya dengan bangga diberitahu oleh manajer bahwa mereka adalah "Toko paling lincah di London". Mereka yakin begitu.
7
Dapat menambahkan masalah lain: selama itu lulus ujian, itu akan baik. Tidak peduli bahwa tes itu sendiri mungkin cacat dan dengan demikian menyebabkan negatif palsu dan / atau positif palsu. Dan tentu saja membutuhkan "cakupan tes 100%" dan segala sesuatu yang memiliki definisi sempurna, menyebabkan tes tidak berguna yang tidak benar-benar menguji apa pun tetapi ditulis hanya untuk mencapai cakupan 100%, kode yang tidak berdokumen karena penghitung cakupan Anda menghitung komentar sebagai kode terbuka, dll.
jwenting
67

Wawancara ( penulis Clojure ) Rich Hickey ini berisi yang berikut ini. Saya merasa 100% simpatik:

Hidup ini singkat dan hanya ada beberapa jam dalam sehari. Jadi, kita harus membuat pilihan tentang bagaimana kita menghabiskan waktu kita. Jika kita habiskan untuk menulis tes, itu saatnya kita tidak menghabiskan melakukan hal lain. Masing-masing dari kita perlu menilai cara terbaik untuk menghabiskan waktu kita untuk memaksimalkan hasil kita, baik secara kuantitas dan kualitas. Jika orang berpikir bahwa menghabiskan lima puluh persen dari waktu mereka menulis tes memaksimalkan hasil mereka — oke untuk mereka. Saya yakin itu tidak benar untuk saya — saya lebih suka menghabiskan waktu memikirkan masalah saya. Saya yakin, bagi saya, ini menghasilkan solusi yang lebih baik, dengan lebih sedikit cacat, daripada penggunaan waktu saya yang lain. Desain yang buruk dengan test suite yang lengkap masih merupakan desain yang buruk.

Pernyataan serupa lainnya dari wawancara buku Donald Knuth in Coders at Work , disalin dari sini :

Seibel: Berbicara tentang kerja praktek, di tengah mengerjakan The Art of Computer Programming, Anda mengambil istirahat sepuluh tahun untuk menulis sistem pengaturan huruf TeX. Saya mengerti Anda menulis TeX versi pertama sepenuhnya dari komputer.

Knuth: Ketika saya menulis TeX awalnya pada tahun 1977 dan '78, tentu saja saya tidak memiliki pemrograman melek tetapi saya memiliki pemrograman terstruktur. Saya menulisnya di buku catatan besar dengan tulisan tangan, dengan pensil. Enam bulan kemudian, setelah saya menyelesaikan seluruh proyek, saya mulai mengetik di komputer. Dan melakukan debug pada Maret '78 sementara saya sudah mulai menulis program pada Oktober '77. Kode untuk itu ada di arsip Stanford — semuanya dengan pensil — dan tentu saja saya akan kembali dan mengganti subrutin ketika saya tahu apa yang seharusnya. Ini adalah sistem generasi pertama, jadi banyak arsitektur yang berbeda dimungkinkan dan harus dibuang sampai saya tinggal dengannya sebentar dan tahu apa yang ada di sana. Dan itu adalah masalah ayam-dan-telur — Anda tidak bisa mengeset sampai Anda memiliki font tetapi kemudian Anda tidak dapat memiliki font sampai Anda bisa mengeset. Tapi pemrograman terstruktur memberi saya ide invarian dan tahu bagaimana membuat kotak hitam yang bisa saya mengerti. Jadi saya memiliki keyakinan bahwa kode itu akan berfungsi ketika saya akhirnya akan men-debug-nya. Saya merasa bahwa saya akan menghemat banyak waktu jika saya menunggu enam bulan sebelum menguji apa pun. Saya cukup yakin bahwa kode itu kira-kira benar.

Seibel: Dan penghematan waktu adalah karena Anda tidak akan menghabiskan waktu membangun perancah dan bertopik untuk menguji kode yang tidak lengkap?

Knuth: Benar.

Joonas Pulakka
sumber
24
Saya pikir Anda harus melihat jenis pekerjaan yang Anda lakukan. Knuth dan Hickey sedang berbicara tentang desain aplikasi baru (inovatif). Jika Anda melihat di mana TDD populer (generalisasi luas), maka Anda menyadari bahwa sebagian besar aplikasi yang ditulis dengan cara TDD sudah memiliki arsitektur yang terkenal.
sebastiangeiger
4
Saya dapat melihat apa yang dimaksud Rich Hickey, tetapi saya ingin menambahkan ini: Pengalaman saya adalah, bahwa ketika Anda menulis tes, Anda harus benar-benar berpikir tentang desain Anda dan berpikir tentang bagaimana Anda membuat kode Anda dapat diuji, yang, dalam pengalaman, menghasilkan desain yang lebih baik.
Niklas H
3
Melihat ketika OP meminta pengalaman negatif dengan TDD, tidak satu pun dari contoh Anda tampaknya relevan dengan pertanyaan ini karena tidak ada yang menunjukkan contoh TDD dalam tindakan.
Winston Ewert
5
@Michael Borgwardt: Ini relatif mudah untuk menambahkan tes ke yang sudah ada, desain yang bagus, untuk menghilangkan bug dalam implementasi. Tetapi menyingkirkan desain yang buruk sering berarti penulisan ulang yang lengkap. Jadi tujuan utama harus dalam mendapatkan desain yang benar; eksekusi lebih mudah untuk diperbaiki nanti.
Joonas Pulakka
4
Sebagian besar aplikasi bisnis tidak memiliki manfaat untuk ditulis dan / atau dikelola oleh Donald Knuth. Masa pakai suatu aplikasi biasanya JAUH lebih lama dari pengembangan utamanya. Saya berharap orang-orang telah menulis lebih banyak tes di proyek saya saat ini. Sekarang pemeliharaan seperti ladang ranjau dari regresi tanpa batas.
Matt H
58

Pengalaman negatif saya dengan TDD adalah pengalaman pertama saya. TDD terdengar hebat bagi saya, saya telah melakukan QA selama bertahun-tahun dan masih memiliki kengerian yang segar di pikiran saya. Saya ingin menghancurkan setiap bug sebelum membuatnya menjadi build. Sayangnya, menggunakan TDD tidak menjamin bahwa Anda akan menulis tes yang bagus. Bahkan, kecenderungan awal saya adalah menulis tes sederhana yang menghasilkan kode sederhana. Benar-benar kode sederhana yang berisi beberapa abstraksi. Tes sangat sederhana yang terjalin dengan internal kelas. Dan sekali Anda memiliki beberapa ribu tes bty itty di tempat Anda yakin tidak merasa seperti Anda bergerak lebih cepat ketika Anda harus mengubah seratus dari mereka untuk memperbaiki kode Anda untuk menggunakan konsep domain X yang sangat penting.

Lampu menyala bagi saya - TDD bukan keterampilan pengujian. Ini keterampilan desain. Ini hanya dapat mengarahkan Anda ke kode yang baik, sederhana, dapat diterapkan dengan praktik dan kesadaran konstan terhadap arah desain yang mengarahkan Anda. Jika Anda menulis tes demi cakupan kode, Anda akan membuat tes rapuh. Jika Anda menulis tes untuk membantu Anda mendesain abstraksi Anda, maka itu hanya cara yang lebih keras untuk menulis kode top-down. Anda dapat melihat kode dari perspektif penelepon terlebih dahulu, yang mendorong Anda untuk membuat hidupnya lebih mudah, daripada mencerminkan internal kelas ke tepi luarnya.

Saya pikir TDD berguna, tetapi saya tidak dogmatis tentang hal itu. Jika "tes tidak-bernilai" itu menyulitkan pemeliharaan - Hapus saja! Saya memperlakukan tes dengan cara yang sama seperti sisa kode. Jika itu bisa dihidupkan kembali dan menjadikannya lebih sederhana, maka lakukanlah!

Saya belum melihatnya secara pribadi, tetapi saya pernah mendengar bahwa beberapa tempat melacak cakupan kode dan jumlah pengujian. Jadi jika pengumpulan metrik adalah efek samping dari TDD, maka saya bisa melihatnya sebagai negatif juga. Saya akan dengan antusias menghapus 1000 baris kode, dan jika itu membatalkan 20 tes dan menurunkan% cakupan kode saya, oh well.

Steve Jackson
sumber
7
Anda memakukannya pada paragraf 2.
Sheldon Warkentin
4
"Saya belum melihatnya secara pribadi, tetapi saya pernah mendengar bahwa beberapa tempat melacak cakupan kode dan jumlah tes" Saya pernah hidup di lingkungan seperti itu dan memang tidak ada kode yang pernah dibuang karena hal itu akan menyebabkan tes gagal. Sampai saya mulai men-debug tes yang sebenarnya, dan menemukan banyak dari mereka memiliki kekurangan yang serius mereka memaksa kode untuk menghasilkan hasil yang salah agar tes lulus. Saat itulah saya menciptakan pertanyaan: "siapa yang menguji tes" yang sejauh ini saya belum pernah mendapat jawaban yang memuaskan dari komunitas TDD. Tes unit untuk tes unit, ada orang?
jwenting
@jwenting - Dan anekdot ini mendukung argumen Rei dengan baik. Saya telah menemukan aspek perlindungan regresi TDD menjadi berlebihan dalam praktek, bahkan jika itu adalah ide yang kuat secara teori. Tes harus diadakan untuk dipertahankan pada tingkat yang sama dengan kode produksi agar dapat berfungsi, dan agak tidak wajar untuk memperlakukan kode non-produksi dengan cara ini - saya melihat "kode busuk" yang sama dengan simulator perangkat keras, generator kode, dll sepanjang waktu.
Steve Jackson
"Tes yang sangat sederhana yang terkait dengan internal kelas" <- ada masalah Anda di sana. Uji hanya untuk antarmuka publik. TDD! = UT
Steven A. Lowe
2
@ StevenA.Lowe - Saya tahu itu sekarang, tetapi 9 tahun yang lalu itu tidak begitu jelas :) "TDD bukan keterampilan pengujian"
Steve Jackson
41

Saya akan pergi mengambil risiko di sini dan menyatakan dengan kejujuran brutal bahwa itu benar - benar buang-buang waktu ritualistik. (Dalam sebagian besar situasi.)

Saya membeli buku tentang Unit Testing yang juga membahas TDD, dan sementara saya setuju dengan manfaat UT, setelah sekitar seratus jam mencoba TDD, saya menyerah karenanya karena berbagai alasan. Saya agak mem-posting di sini, tetapi TDD:

  1. Dokumentasi tidak lebih baik dari dokumentasi asli.
  2. Tidak menangkap bug atau regresi .
  3. Tidak benar-benar membuat desain saya lebih baik dari pada akhirnya jika saya menerapkan beberapa pemrograman fungsional dan konsep kompabilitas .
  4. Adalah waktu yang bisa lebih baik dihabiskan untuk melakukan tinjauan kode atau memoles dokumentasi dan spesifikasi.
  5. Memberi manajer rasa aman palsu ketika mereka melihat daftar ratusan ikon hijau.
  6. Meningkatkan produktivitas dalam implementasi algoritma dengan pemetaan input-output yang terbatas.
  7. Canggung dalam hal Anda mungkin tahu apa yang Anda lakukan sebagai hasil dari TDD, tetapi Anda tidak mendapatkan pemahaman tentang mengapa itu bekerja dengan sangat baik, mengapa desain Anda terlihat seperti itu.

Kekhawatiran lain adalah tingkat kesempurnaan yang diperdebatkan dimana seseorang harus melakukan TDD untuk melakukannya dengan sukses. Beberapa bersikeras bahwa jika TDD tidak dilakukan terus-menerus oleh semua orang di tim sejak awal proyek, Anda hanya akan menderita. Yang lain bersikeras bahwa tidak ada yang pernah melakukan TDD oleh buku. Jika keduanya benar, maka praktisi TDD menderita, apakah mereka menyadarinya atau tidak.

Tentu saja, jika diperdebatkan bahwa dengan melakukan hal-hal seperti TDD Anda akan sampai pada desain yang dapat bekerja dengan mudah dengan TDD, well, ada banyak cara yang lebih cepat untuk mencapai itu - yaitu, dengan benar-benar mempelajari konsep-konsep kompabilitas. Ada banyak sumber daya di luar sana, bahkan banyak teori matematika yang ketat (sebagian besar dalam pemrograman fungsional tetapi juga di bidang lain). Mengapa tidak menghabiskan semua waktu TDD Anda untuk belajar ?

Secara budaya, TDD menunjukkan gejala menjadi praktik ritualistik. Ia merasa bersalah; itu mendorong prosedur lebih dari pemahaman; memiliki banyak doktrin dan slogan ("berpura-puralah sampai Anda membuatnya" benar-benar cukup mengkhawatirkan jika Anda melihatnya secara objektif). Definisi Wikipedia tentang kata "ritual" sebenarnya cukup tepat:

Dalam psikologi, istilah ritual kadang-kadang digunakan dalam pengertian teknis untuk perilaku berulang yang secara sistematis digunakan oleh seseorang untuk menetralisir atau mencegah kecemasan; itu adalah gejala gangguan obsesif-kompulsif.

Rei Miyasaka
sumber
Perspektif yang sangat menarik yaitu: ritual. Anda juga mendapatkan pengertian, di beberapa kalangan, bahwa komitmen seorang programmer terhadap keahliannya dinilai semata-mata sebanding dengan kepatuhannya pada TDD.
yalestar
Saya akan mengatakan dalam beberapa situasi dapat meningkatkan desain, tetapi sebagian besar saat itulah desain harus sangat modular dengan antarmuka publik yang terdefinisi dengan sangat baik dan mudah digunakan. Menulis tes untuk itu sebelum mengimplementasikan perpustakaan itu sendiri dalam kasus-kasus itu dapat membantu menghilangkan bug di antarmuka publik serta memaksa modularitas itu.
jwenting
8
@jwenting People melakukan TDD karena mereka tidak tahu apa yang membuat desain modular, sehingga mereka tidak pernah bisa melepas roda pelatihan 35 "dari motor 40" mereka. Membuat desain modular selalu merupakan tugas yang dapat dikelola jika Anda memahami konsep-konsepnya, karena setiap dilema dalam desain Anda akan memiliki ukuran yang dapat dikelola karena pada kenyataannya, dalam konsepnya, dalam proses menjadi modular. Saya tidak setuju bahwa TDD efektif dalam memaksakan modularitas, tetapi saya tidak setuju bahwa seseorang perlu dipaksa untuk membuat desain modular. Desain modular adalah keterampilan yang bisa diajar dan dipelajari dengan sempurna.
Rei Miyasaka
@jwenting Mengenai kegunaan antarmuka publik, ada dua aliran pemikiran di antara para praktisi TDD mengenai hal itu, keduanya tidak diinginkan: buat semuanya publik sehingga dapat diuji, atau biarkan hal-hal pribadi jika tidak boleh diuji lagi. . Yang pertama memaksa detail implementasi yang tidak perlu untuk diekspos kepada pengguna akhir (yang berpotensi dapat disalahgunakan atau dieksploitasi), dan yang terakhir memaksa unit test untuk lebih dekat dengan tes sistem. Tentu, Anda bisa menggunakan alat pengujian unit untuk mengakses privat, tapi itu tidak masuk akal untuk dilakukan di TDD.
Rei Miyasaka
1
@Kall Dalam wawancara itu, dia mengatakan "sekitar 15 hingga 35% lebih banyak waktu" - bukan hanya 15% seperti yang telah Anda kutip padanya. Studi ini juga hanya melibatkan Java / C ++ / C # (mungkin C # 2, diberi tanggal) - semua bahasa dari paradigma OOP imperatif yang sama. Saya tentu saja lebih dari 15% dan mungkin lebih dari 35% lebih produktif dalam bahasa fungsional (dan bahkan dalam C # 3), dan saya menghasilkan lebih sedikit bug yang menulis stateless, kode komposer - jenis bug yang sama dengan pengujian yang memperbaiki, karena kedua hal tersebut menyelesaikan jenis masalah yang sama persis. Dengan kata lain, tentu saja, 60-90% pengurangan bug, tetapi dibandingkan dengan apa ?
Rei Miyasaka
18

Untuk menambahkan, masalah lain dengan TDD yang saya perhatikan adalah:

TDD menyebabkan perubahan yang tidak disengaja dalam fokus tim pengembangan dari Kode Kualitas ke Testcases dan Cakupan Kode! Saya pribadi tidak suka TDD karena membuat saya kurang kreatif dan membuat pengembangan perangkat lunak proses mekanik yang membosankan ! Unit testcases berguna ketika digunakan secara bijaksana tetapi menjadi beban ketika diperlakukan tujuan pengembangan perangkat lunak.

Saya kenal seorang pria yang seorang manajer dan secara teknis membosankan sekali terobsesi dengan TDD. Itu adalah hal yang sangat ajaib baginya sehingga dia percaya akan membawa solusi ajaib untuk semua masalah dalam perangkat lunaknya yang buruk arsitekturnya dengan kode yang paling tidak bisa dirawat. Belum lagi apa yang terjadi pada proyek itu - gagal total di tangannya, sementara semua testcenya berwarna hijau. Saya kira TDD membantunya mendapatkan semacam informasi statistik seperti "99/100 kasus saya berwarna hijau" dll dan itulah alasan obsesinya karena ia tidak akan pernah dapat mengevaluasi kualitas atau menyarankan peningkatan dalam desain.

Kiran Ravindranathan
sumber
2
Kedengarannya seperti PHB sih! Ini mengingatkan saya pada perusahaan yang memperkenalkan skema bonus - yang terjadi tentu saja adalah pengembang bukannya berfokus pada kode kualitas, fokus pada memenuhi apa pun persyaratan bonusnya. Mau tidak mau Anda mendapatkan kode crappier. (Ada juga analogi dengan krisis perbankan saat ini :-))
TrojanName
Nah TDD bukanlah teknik Manajemen Proyek, jadi tidak heran kalau manajer-wannabe Anda gagal. Di sisi lain saya tidak merasa kurang kreatif, saya bahkan merasa lebih kreatif karena mengembangkan tes secara otomatis memberi saya pandangan lain pada kode saya. Namun saya setuju bahwa fokusnya harus kode produksi, dan tes tidak boleh mengacaukan arsitektur perangkat lunak yang baik.
Alex
Cakupan kode menjadi perhatian Unit Testing, bukan TDD. TDD hanya peduli tentang fitur dan pengujian melalui antarmuka publik.
Steven A. Lowe
14

Pengalaman negatif utama saya adalah mencoba menggunakan TDD untuk mengedit kode programmer lain yang tidak memiliki tes, atau tes integrasi yang sangat, sangat dasar. Ketika saya pergi untuk menambahkan fitur, atau memperbaiki masalah dengan kode tersebut; Saya lebih suka menulis tes pertama (cara TDD). Sayangnya, kodenya tergabung erat, dan saya tidak dapat menguji apa pun tanpa banyak refactoring.

Refactoring adalah latihan yang bagus, tetapi diperlukan untuk membuat kode menjadi kondisi yang dapat diuji. Dan setelah langkah ini, saya tidak memiliki checks and balances untuk melihat apakah perubahan saya merusak sesuatu; singkat menjalankan aplikasi dan memeriksa setiap kasus penggunaan.

Di sisi lain, menambahkan fitur / memperbaiki bug ke proyek TDD menjadi sangat mudah. Secara alami, kode yang ditulis dengan TDD biasanya cukup dipisahkan dengan potongan-potongan kecil untuk dikerjakan.

Bagaimanapun, TDD adalah pedoman. Ikuti sampai ke titik di mana Anda menemukan Anda mendapatkan efektivitas maksimum. Cakupan pengujian yang layak dan kode yang dipisahkan, kode yang ditulis dengan baik.

Sheldon Warkentin
sumber
1
Jika sulit untuk menulis tes unit, umumnya ada pemisahan keprihatinan yang buruk. Saya tidak melihat ini sebagai kesalahan TDD, jika ada sesuatu dengan cepat membuat masalah ini jelas.
Tom Kerr
7
Itu bukan pengalaman negatif dengan TDD, itu pengalaman negatif dengan kode jelek.
Rei Miyasaka
13

Saya membuat pengalaman yang kadang-kadang saya terlalu bergantung pada tes saya ketika datang ke desain sistem. Saya pada dasarnya terlalu rendah dalam detail implementasi seluk-beluk untuk mengambil langkah mundur untuk melihat gambar yang lebih besar. Ini sering menghasilkan desain yang rumit dan tidak perlu. Saya tahu, saya seharusnya memperbaiki kode tetapi kadang-kadang saya mendapat kesan bahwa saya bisa menghemat banyak waktu dengan mengambil langkah mundur lebih sering.

Yang sedang berkata, jika Anda memiliki kerangka kerja seperti rel di mana keputusan arsitektur Anda sangat terbatas masalah ini pada dasarnya tidak ada.

Masalah lain adalah ketika Anda memercayai tes Anda secara membabi buta. Kebenarannya adalah - seperti kode lainnya - tes Anda dapat memiliki bug juga. Jadi, sama pentingnya dengan tes Anda seperti Anda terhadap implementasi Anda.

sebastiangeiger
sumber
2
Mungkin Anda harus menulis beberapa tes untuk tes Anda! : p ...... I Kid, I Kid
Aren
+1 +1 +1 +1 (jika saya memiliki 3 akun dummy). Kalimat # 2 sangat berwawasan dan bebas dari bias konfirmasi TDD yang terlalu lazim.
tgm1024
11

Sebagai penggemar berat TDD saya terkadang melihat kekurangan ini

  • Godaan untuk menulis terlalu banyak tes demi cakupan kode hampir 100%. Menurut pendapat saya tidak perlu menulis tes
    • untuk pengambil / setter properti sederhana
    • untuk setiap kasus ketika pengecualian dilemparkan
    • yang memeriksa fungsi yang sama melalui berbagai lapisan. (Contoh: jika Anda memiliki unittest untuk memeriksa validasi input untuk setiap parameter maka tidak perlu mengulang semua tes ini melalui tes integrasi juga)
  • Biaya pemeliharaan kode uji untuk pengujian serupa, yang hanya sedikit berbeda (dibuat melalui duplikasi kode (alias copy-paste-inheritance)). Jika Anda sudah memilikinya, mudah untuk membuat yang serupa. Tetapi jika Anda tidak memperbaiki kode tes, dengan menghilangkan duplikasi kode menjadi metode pembantu, Anda mungkin perlu waktu untuk memperbaiki tes jika rincian implementasi kode bisnis Anda berubah.

  • Jika Anda berada di bawah tekanan waktu, Anda mungkin tergoda untuk menghilangkan tes yang rusak (atau berkomentar keluar) daripada memperbaikinya . Dengan cara ini Anda kehilangan investasi dalam tes

k3b
sumber
2
+1: "Godaan untuk menulis terlalu banyak tes demi hampir 100% codecoverage.": Saya jatuh ke dalam perangkap ini sekali, dan setelah menghabiskan berjam-jam menulis semua tes unit, hanya tiga bug yang saya temukan dalam kode saya adalah tidak dicakup oleh unit test dan dapat dengan mudah ditemukan dengan men-debug kode langkah-demi-langkah.
Giorgio
9

Saya belum menemukan lebih dari satu skenario sebagai pengembang game di mana TDD berharga. Dan contoh di mana itu, adalah sepotong kode yang murni bersifat matematika dan membutuhkan pendekatan yang kuat untuk menguji sejumlah besar kasus tepi secara bersamaan - suatu kebutuhan yang langka.

Mungkin sesuatu, suatu hari nanti akan berubah pikiran, tetapi di antara praktik XP, ide refactoring tanpa ampun , dan kode yang berkembang bentuknya sendiri jauh lebih penting dan mengarah pada produktivitas terbesar bagi saya, lih. kutipan dari makalah oleh James Newkirk :

Kesederhanaan - "Apa hal paling sederhana yang bisa berhasil?"
Pesannya sangat jelas. Mengingat persyaratan untuk hari ini, rancang dan tulis perangkat lunak Anda. Jangan mencoba mengantisipasi masa depan, biarkan masa depan terungkap. Ini akan sering melakukan ini dengan cara yang sangat tidak terduga membuat mengantisipasi biaya yang seringkali terlalu mahal untuk dibeli. "

Konsep keberanian dan pengetatan putaran umpan balik yang dia sebutkan juga, menurut saya, adalah kunci produktivitas.

Insinyur
sumber
9
Masalahnya adalah, tanpa unit test bagaimana Anda tahu bahwa hasil refactoring Anda tanpa ampun dalam kode yang melakukan hal yang sama? Dalam pengalaman saya, saya telah menemukan bahwa tergantung pada masalahnya, saya membutuhkan waktu lebih sedikit untuk menulis tes + kode daripada menulis kode sendiri! Alasan utamanya bermuara pada kenyataan bahwa untuk beberapa masalah saya dapat mencoba re-faktor dan menguji ulang secara otomatis jauh lebih cepat daripada yang saya dapat mengujinya secara manual, yang dapat meningkatkan kecepatan iterasi cukup signifikan.
Mark Booth
6
Untuk permainan, sangat sering hasilnya dapat dilihat. Jika mereka dapat dilihat, dan tampil cukup baik, mereka akan diterima, karena permainan memang dimaksudkan untuk menjadi pengalaman subjektif. Di sisi lain, mengambil mis. Diablo 2 sebagai contoh, jumlah kesalahan dalam formula pertempuran menunjukkan di mana TDD akan membawa nilai besar dan menyelamatkan mereka sejumlah besar pekerjaan di patch. Untuk masalah yang didefinisikan dengan sangat baik seperti memecahkan persamaan, dan di mana ini tidak dapat dinilai oleh output visual saat runtime, TDD adalah harus-harus untuk memastikan kebenaran. Tapi itu adalah sebagian kecil dari kode di sebagian besar gim.
Insinyur
Juga patut disebutkan bahwa karena laju di mana simulasi berjalan, lebih baik untuk menonton variabel secara real-time, di layar, saat sim berjalan, daripada duduk dengan jutaan-baris logfiles untuk melihat posting fakta.
Insinyur
3
Tes unit membuat refactoring jauh lebih mudah, menurut pengalaman saya.
Tom Kerr
1
@Nick Masalah besar dalam industri game adalah tenggat waktu, yang selalu - "kami harus memberikan setengah tahun yang lalu". Saya pikir waktu bermain melawan unit-test di lingkungan yang dibatasi waktu. Dalam beberapa kasus itu bukan keputusan yang benar, tetapi dalam kebanyakan kasus pengiriman tanpa penulisan tes lebih cepat. Tergantung, sangat tergantung ...
Coder
7

Pengalaman TDD negatif saya, sebatas mungkin, hanya mengetahui dari mana harus memulai! Sebagai contoh, saya akan mencoba untuk melakukan sesuatu TDD dan entah tidak tahu di mana harus mulai melarang pengujian hal-hal sepele (bisakah saya membuat Fooobjek baru, dapatkah saya meneruskan Quuxke Baz, dan sejenisnya. Tes yang tidak menguji apa pun ), atau jika saya mencoba mengimplementasikannya dalam proyek yang ada maka saya menemukan bahwa saya harus menulis ulang berbagai kelas untuk dapat menggunakannya dalam TDD. Hasil akhirnya adalah bahwa saya dengan cepat meninggalkan gagasan itu sepenuhnya.

Mungkin tidak membantu yang sering saya satu-satunya orang di seluruh perusahaan yang tahu apa pengujian unit (TDD atau sebaliknya) dan mengapa itu hal yang baik.

Wayne Molina
sumber
1
Di sinilah kerangka mengejek masuk. Instantiate Foodengan benda-benda tiruan daripada Quuxdan Bazlangsung, maka Anda dapat memanggil fungsi yang ingin Anda uji dan kemudian memeriksa bahwa tiruan itu dipanggil dengan fungsi yang Anda harapkan. Objek tiruan adalah teknologi yang memungkinkan yang membantu memisahkan unit dan membuatnya unit dapat diuji. Inilah sebabnya mengapa lajang jahat, karena Anda sering tidak bisa begitu saja mengejek mereka. * 8 ')
Mark Booth
7

Fanatik TDD.

Bagi saya, mereka hanyalah satu dari sekian banyak orang gila agama yang mengetuk pintu saya, mencoba membuktikan bahwa cara saya dalam melakukan berbagai hal tidak dapat diperbaiki dan satu-satunya jalan menuju keselamatan adalah Yesus, Kent Back, atau Unit Testing.

IMO, kebohongan terbesar mereka adalah bahwa TDD akan menuntun Anda untuk menyelamatkan desain algoritma yang lebih baik. Lihat pemecah Soduku terkenal yang ditulis dalam TDD: di sini , di sini , di sini , di sini dan di sini

Dan membandingkannya, pemecah sudoku Peter Norvig dilakukan bukan dengan menggunakan TDD, tetapi menggunakan teknik kuno: http://norvig.com/sudoku.html

Cesar Canassa
sumber
Lihat kita bisa berdebat terus tentang ini. Tapi saya punya banyak pekerjaan yang harus dilakukan sejak saya lulus dari universitas Fullsail dengan gelar saya dalam desain game. Berdasarkan kursus saya dan pekerjaan saya yang sangat menuntut, saya dapat mengatakan bahwa TDD benar-benar mengalahkan pengembangan baris-demi-baris (kurangnya desain) panik programmer. Lihat, saya tidak akan mengatakannya tetapi itu benar: Sebagian besar pengembang yang pergi ke program CS universitas normal sebagian besar tidak lulus, beberapa yang sangat tidak pindah ke pengembangan perangkat lunak, dan di atas itu banyak dari mereka yang hampir tidak mendapatkan , baris demi baris. Universitas Fullsail memiliki
Zombies
selesaikan kursus dalam pengembangan yang digerakkan oleh tes saja dan yang benar-benar membuat pengembang berada di jalur yang benar (sebagai lawan mengimplementasikan daftar tertaut di c ++).
Zombi
Tautan rusak Bung!
lmiguelvargasf
Ini bertahun-tahun kemudian, tetapi @Zombies, lihat "Bias Konfirmasi". Banyak dari apa yang kita semua diajarkan di CS di perguruan tinggi jatuh ke dalam kategori itu. Lihatlah pemberhentian "angka ajaib" yang tak
terduga
Lol man saya trolling ... saya menulis bahwa sejak lama saya lupa tentang permata kecil itu.
Zombies
5

Jika Anda menggunakan TDD dari artikel "fanatik" ini, Anda akan merasa tidak aman karena merasa perangkat lunak Anda tidak memiliki kesalahan.

Dainius
sumber
1
Bisakah Anda mendapatkan perasaan lain selain mengetahui bahwa untuk serangkaian input tertentu, perangkat lunak Anda mengembalikan serangkaian output tertentu?
selama Anda mengerti bahwa tdd adalah proses pengembangan dan bukan aturan emas untuk menyelesaikan masalah apa pun, tidak apa-apa. Tetapi sebagian besar orang yang mengusulkan untuk menggunakan proses ini lupa bahwa itu proses pengembangan dan karena proses lainnya memiliki sisi terang dan sisi gelap. Mereka mengatakan kepada semua orang bahwa jika Anda akan menggunakan tdd, Anda akan memiliki perangkat lunak bebas bug, karena Anda akan menggunakan tes untuk mencakup setiap fitur. Dan biasanya itu tidak benar. Cara terbaik akan ada tes untuk setiap kasus (atau setidaknya fitur), tetapi tes adalah program (yang memiliki bug) dan hanya tes kotak hitam.
Dainius
4

TDD memiliki beberapa manfaat:

  • Anda fokus pada bagaimana memanggil kode Anda dan apa yang diharapkan terlebih dahulu (saat Anda menulis tes terlebih dahulu) alih-alih berfokus pada penyelesaian masalah dan kemudian Anda membuat panggilan dari aplikasi. Modularitas membuatnya lebih mudah untuk diejek dan dibungkus.
  • Tes memastikan bahwa program Anda bekerja sama sebelum dan sesudah refactoring. Ini tidak berarti program Anda bebas kesalahan, tetapi tetap bekerja dengan cara yang sama.

TDD adalah tentang investasi jangka panjang. Upaya ini terbayar ketika Anda mencapai mode pemeliharaan aplikasi Anda, dan jika aplikasi tidak direncanakan untuk mencapai titik itu, Anda mungkin tidak pernah memulihkan investasi.

Saya menganggap siklus merah-hijau TDD dengan langkah-langkah bayi mirip dengan daftar periksa untuk pesawat. Sangat menjengkelkan dan melelahkan untuk memeriksa setiap hal di dalam pesawat sebelum lepas landas terutama jika itu sederhana (langkah-langkah TDD bayi), tetapi telah ditemukan bahwa hal itu meningkatkan keselamatan. Selain memverifikasi semuanya berfungsi, itu pada dasarnya mengatur ulang pesawat . Dengan kata lain, sebuah pesawat dinyalakan ulang sebelum setiap take-off.

user1249
sumber
3
Poin manfaat 2 dapat dicapai dengan tes unit sederhana tanpa pendekatan TDD juga. Manfaat 1 Anda harus melakukan bagaimanapun juga. (Berfokus pada API) Masih memungkinkan untuk membuat API jelek menggunakan TDD, tapi ya, Anda dijamin akan berfungsi (untuk tes tertulis).
Steven Jeuris
2
Pertanyaannya bukan menanyakan tentang manfaat TDD. Sudah ada banyak pertanyaan lain tentang itu.
Aaronaught
1
@aaronaught, saya membahas poin rasa sakitnya.
Jawaban harus menjawab pertanyaan .
Aaronaught
1
@aaronaught, lalu tulis beberapa dari itu.
3

Pengalaman negatif saya tentang TDD adalah sesuatu yang saya rasakan dengan banyak hal baru dan hyped. Sebenarnya saya menikmati TDD karena memastikan validitas kode saya, dan bahkan lebih penting: saya dapat mengenali tes yang gagal, setelah menambahkan kode baru atau segala jenis refactoring.

Yang mengganggu saya tentang TDD adalah kenyataan bahwa ada banyak aturan atau pedoman tentang hal itu. Karena ini masih sangat baru, kami sebagian besar dari kita mengalami untuk menjadi pemula di TDD. Jadi apa yang berhasil untuk sebagian dari kita, mungkin tidak bekerja untuk yang lain. Yang ingin saya katakan adalah, bahwa tidak ada cara nyata "salah atau benar" untuk melakukan TDD: Ada cara yang bekerja untuk saya - dan tim saya jika saya memilikinya.

Jadi selama Anda menulis tes - sebelum atau setelah kode produksi tidak terlalu penting IMHO - saya tidak yakin apakah tes didorong benar-benar berarti Anda harus mengikuti semua pedoman yang dinyatakan sekarang, karena mereka belum terbukti menjadi solusi ideal untuk pekerjaan sehari-hari. Jika Anda menemukan cara yang lebih baik dalam menulis tes, Anda harus mempostingnya di blog, bahas di sini, atau tulis artikel tentang itu. Jadi dalam sepuluh tahun atau lebih kita mungkin telah berbagi pengalaman yang cukup untuk dapat mengetahui aturan TDD mana yang dapat dianggap baik atau tidak dalam situasi tertentu.

Alex
sumber
+1 Komentar luar biasa. Benar-benar tidak harus menjadi satu-satunya jalan yang benar atau tidak sama sekali.
unpythonic
3

Saya telah, pada lebih dari satu kesempatan, menulis kode yang saya buang pada hari berikutnya karena canggung. Saya memulai kembali dengan TDD dan solusinya lebih baik. Jadi saya belum punya terlalu banyak pengalaman TDD negatif. Namun demikian, saya telah menghabiskan waktu untuk memikirkan masalah dan mencari solusi yang lebih baik di luar ruang TDD.

pengguna23356
sumber
1
Biasanya upaya kedua akan memberi Anda lebih banyak wawasan tentang masalah daripada upaya pertama, TDD atau tidak.
wobbily_col
3

Saya telah menemukan TDD berkinerja buruk ketika datang ke sistem yang muncul. Saya adalah pengembang permainan video, dan baru-baru ini menggunakan TDD untuk membuat sistem yang menggunakan beberapa perilaku sederhana untuk membuat gerakan yang tampak realistis untuk suatu entitas.

Misalnya, ada perilaku yang bertanggung jawab untuk memindahkan Anda dari area berbahaya dari berbagai jenis, dan yang bertanggung jawab untuk memindahkan Anda ke area menarik dari berbagai jenis. Dengan menggabungkan output dari masing-masing perilaku menciptakan gerakan akhir.

Nyali sistem diimplementasikan dengan mudah, dan TDD berguna di sini untuk menentukan apa yang harus bertanggung jawab atas setiap subsistem.

Namun saya mengalami masalah ketika menentukan bagaimana perilaku berinteraksi, dan yang lebih penting bagaimana mereka berinteraksi dari waktu ke waktu. Seringkali tidak ada jawaban yang benar, dan meskipun tes awal saya lulus, QA dapat terus menemukan kasus tepi di mana sistem tidak berfungsi. Untuk menemukan solusi yang benar, saya harus mengulangi beberapa perilaku yang berbeda, dan jika saya memperbarui tes setiap kali untuk mencerminkan perilaku baru sebelum saya memeriksa mereka bekerja dalam permainan, saya mungkin akhirnya membuang tes berulang kali. Jadi saya menghapus tes-tes itu.

Saya seharusnya memiliki tes yang lebih kuat yang menangkap kasus-kasus tepi yang ditemukan QA, tetapi ketika Anda memiliki sistem seperti ini yang berada di atas banyak sistem fisika dan gameplay, dan Anda berurusan dengan perilaku dari waktu ke waktu, itu menjadi sedikit mimpi buruk untuk menentukan dengan tepat apa yang terjadi.

Saya hampir pasti membuat kesalahan dalam pendekatan saya, dan seperti saya katakan untuk nyali sistem TDD bekerja dengan cemerlang, dan bahkan mendukung beberapa refaktor yang optimal.

tenpn
sumber