Pengantar singkat untuk pertanyaan ini. Saya telah menggunakan TDD sekarang dan belakangan ini BDD selama lebih dari satu tahun sekarang. Saya menggunakan teknik seperti mengejek untuk membuat menulis tes saya lebih efisien. Akhir-akhir ini saya telah memulai proyek pribadi untuk menulis sedikit program pengelolaan uang untuk diri saya sendiri. Karena saya tidak punya kode warisan, itu adalah proyek yang sempurna untuk memulai dengan TDD. Sayangnya saya tidak mengalami banyak kesenangan dari TDD. Itu bahkan merusak kesenangan saya sehingga saya menyerah pada proyek.
Apa masalahnya? Yah, saya telah menggunakan pendekatan seperti TDD untuk membiarkan tes / persyaratan berevolusi desain program. Masalahnya adalah lebih dari setengah waktu pengembangan untuk tes menulis / refactor. Jadi pada akhirnya saya tidak ingin menerapkan lebih banyak fitur karena saya perlu refactor dan menulis ke banyak tes.
Di tempat kerja saya memiliki banyak kode warisan. Di sini saya menulis lebih banyak dan lebih banyak tes integrasi dan penerimaan dan lebih sedikit tes unit. Ini tampaknya bukan pendekatan yang buruk karena bug sebagian besar terdeteksi oleh tes penerimaan dan integrasi.
Gagasan saya adalah, pada akhirnya saya bisa menulis lebih banyak tes integrasi dan penerimaan daripada tes unit. Seperti yang saya katakan untuk mendeteksi bug, tes unit tidak lebih baik dari tes integrasi / penerimaan. Tes unit juga baik untuk desain. Karena saya sering menulis banyak dari mereka, kelas saya selalu dirancang agar dapat diuji dengan baik. Selain itu, pendekatan untuk membiarkan tes / persyaratan memandu desain dalam banyak kasus mengarah ke desain yang lebih baik. Keuntungan terakhir dari unit test adalah mereka lebih cepat. Saya telah menulis cukup tes integrasi untuk mengetahui, bahwa mereka bisa hampir secepat unit test.
Setelah saya mencari melalui web saya menemukan bahwa ada ide yang sangat mirip dengan saya yang disebutkan di sana - sini . Apa pendapatmu tentang ide ini?
Sunting
Menanggapi pertanyaan-pertanyaan satu contoh di mana desainnya bagus, tetapi saya membutuhkan refactoring besar untuk persyaratan berikutnya:
Pada awalnya ada beberapa persyaratan untuk menjalankan perintah tertentu. Saya menulis parser perintah yang dapat diperpanjang - yang mem-parsing perintah dari beberapa jenis command prompt dan memanggil yang benar pada model. Hasilnya diwakili dalam kelas model tampilan:
Tidak ada yang salah di sini. Semua kelas independen satu sama lain dan saya dapat dengan mudah menambahkan perintah baru, menampilkan data baru.
Persyaratan berikutnya adalah, bahwa setiap perintah harus memiliki representasi tampilan sendiri - semacam pratinjau hasil perintah. Saya mendesain ulang program untuk mencapai desain yang lebih baik untuk persyaratan baru:
Ini juga bagus karena sekarang setiap perintah memiliki model tampilan sendiri dan oleh karena itu pratinjau sendiri.
Masalahnya adalah, bahwa parser perintah diubah untuk menggunakan parsing berbasis token dari perintah dan dilucuti dari kemampuannya untuk mengeksekusi perintah. Setiap perintah memiliki model tampilan sendiri dan model tampilan data hanya mengetahui model tampilan perintah saat ini daripada mengetahui data yang harus ditampilkan.
Yang ingin saya ketahui pada saat ini adalah, jika desain baru tidak melanggar persyaratan yang ada. Saya tidak perlu mengubah APA SAJA dari tes penerimaan saya. Saya harus memperbaiki atau menghapus hampir SETIAP unit test, yang merupakan tumpukan pekerjaan.
Apa yang ingin saya tunjukkan di sini adalah situasi umum yang sering terjadi selama pengembangan. Tidak ada masalah dengan desain lama atau baru, mereka hanya berubah secara alami dengan persyaratan - bagaimana saya memahaminya, ini adalah salah satu keunggulan TDD, bahwa desain berkembang.
Kesimpulan
Terima kasih atas semua jawaban dan diskusi. Dalam ringkasan diskusi ini saya telah memikirkan suatu pendekatan yang akan saya uji dengan proyek saya berikutnya.
- Pertama-tama saya menulis semua tes sebelum menerapkan hal seperti yang selalu saya lakukan.
- Untuk persyaratan, pada awalnya saya menulis beberapa tes penerimaan yang menguji seluruh program. Lalu saya menulis beberapa tes integrasi untuk komponen di mana saya perlu menerapkan persyaratan. Jika ada komponen yang bekerja sama erat dengan komponen lain untuk mengimplementasikan persyaratan ini, saya juga akan menulis beberapa tes integrasi di mana kedua komponen diuji bersama. Terakhir tetapi tidak kalah pentingnya jika saya harus menulis algoritma atau kelas lain dengan permutasi tinggi - misalnya serializer - saya akan menulis unit test untuk kelas khusus ini. Semua kelas lain tidak diuji tetapi tes unit apa pun.
- Untuk bug prosesnya dapat disederhanakan. Biasanya bug disebabkan oleh satu atau dua komponen. Dalam hal ini saya akan menulis satu tes integrasi untuk komponen yang menguji bug. Jika terkait dengan algoritma, saya hanya akan menulis unit test. Jika tidak mudah untuk mendeteksi komponen di mana bug terjadi, saya akan menulis tes penerimaan untuk menemukan bug - ini harus menjadi pengecualian.