Sedikit lebih dari setahun yang lalu saya cukup beruntung untuk dapat istirahat 9 bulan dari pekerjaan. Saya memutuskan bahwa pada waktu itu saya akan mengasah keterampilan C # saya. Saya mulai mengerjakan banyak proyek dan memaksa diri saya untuk mengikuti TDD.
Itu adalah proses yang cukup mencerahkan.
Itu sulit pada awalnya, tetapi seiring waktu saya belajar bagaimana menulis kode yang lebih dapat diuji (yang, ternyata, cenderung menjadi kode SOLID) dan dalam proses itu saya juga mempertajam keterampilan desain OO saya.
Sekarang saya kembali ke dunia kerja dan saya melihat sesuatu yang aneh.
Saya lebih suka tidak mengikuti TDD.
Saya menemukan TDD memperlambat saya dan sebenarnya membuat lebih sulit untuk merancang aplikasi yang bersih.
Sebagai gantinya, saya telah mengadopsi pendekatan yang sedikit berbeda (secara besar-besaran):
- Pilih sepotong pekerjaan vertikal
- Kembangkan prototipe yang berfungsi
- Refactor sampai semuanya bagus dan rapi
- Duduk menghargai kode SOLID dan diuji indah yang saya tulis.
Anda mungkin telah memperhatikan bahwa langkah 1 bukan "mendefinisikan permukaan publik dari target pengujian saya" dan langkah 2 tidak "menguji bejesus keluar dari permukaan publik tersebut." Anda mungkin juga memperhatikan bahwa tidak ada langkah yang melibatkan pengujian. Saya sedang menulis kode yang dapat diuji, tapi saya belum mengujinya ... dulu.
Sekarang, saya ingin memperjelas bahwa saya sebenarnya tidak meninggalkan pengujian apa pun. Kode yang saya tulis berfungsi . Ini bekerja karena saya mengujinya secara manual.
Saya juga ingin menjelaskan bahwa saya tidak meninggalkan semua pengujian otomatis juga. Di sinilah proses saya berbeda. Dan inilah mengapa saya mengajukan pertanyaan ini.
Secara teori TDD. Tidak dalam praktek.
Proses saya telah berkembang sedikit dan saya telah mencapai keseimbangan antara TDD dan tidak ada tes yang saya temukan sangat produktif dan juga cukup aman. Bunyinya sebagai berikut:
- Terapkan irisan vertikal kerja dengan pengujian dalam pikiran, tetapi jangan menulis tes apa pun.
- Jika jalan (misalnya, sebulan kemudian) irisan itu perlu modifikasi
- Tulis Tes Unit, Tes Integrasi, Tes Perilaku, dll yang menjamin potongan pekerjaan sudah benar
- Ubah kodenya
- Jika irisan itu tidak perlu modifikasi,
- Tidak melakukan apapun
Dengan hanya menggeser beban menulis tes dari sebelum menulis kode ke sebelum mengubah kode saya sudah bisa menghasilkan kode kerja yang lebih banyak. Dan, ketika saya melakukan tes menulis saya menulis lebih sedikit dari mereka tetapi mencakup hampir sama banyak (ROI lebih tinggi).
Saya suka proses ini, tapi saya khawatir ini mungkin tidak skala dengan baik. Keberhasilannya bergantung pada pengembang yang rajin menulis tes sebelum mereka mengubah hal-hal. Dan itu sepertinya risiko yang cukup besar. Tapi, TDD memiliki risiko yang sama.
Jadi, apakah saya akan ke [BT] DD sih, atau apakah ini bentuk umum dari pengkodean dan pengujian pragmatis?
Saya ingin tetap bekerja dengan cara ini. Apa yang bisa saya lakukan untuk membuat proses ini bekerja dalam jangka panjang?
catatan:Saya adalah satu-satunya pengembang di proyek saya dan saya bertanggung jawab untuk semuanya: Pengumpulan persyaratan, desain, arsitektur, pengujian, penyebaran, dll. Saya menduga inilah sebabnya proses saya bekerja.
sumber
If that slice doesn't need modification
. lizkeogh.com/2012/06/24/beyond-test-driven-developmentJawaban:
Untuk membuat proses bekerja dalam jangka panjang saya akan menulis tes ketika kode sedang ditulis.
Yang tampaknya bertentangan dengan pendekatan Anda. Namun Anda telah mengajukan pertanyaan, jadi saya akan memberi Anda pendapat saya:
Anda tidak harus menulis tes sebelum kode. lupakan kemurnian itu. Namun Anda ingin menulis tes sekitar waktu itu.
Setelah kode berfungsi, Anda harus mengubahnya sedikit, mengeluarkan beberapa bug (kita berbicara tentang skala waktu berjam-jam di sini), Anda kemudian pada titik pengetahuan maksimum tentang apa yang dilakukan kode. Ini adalah saat yang tepat untuk menulis tes yang menangkap pengetahuan Anda.
Meninggalkan ini sampai nanti berarti pengetahuan akan (secara alami) berkurang seiring waktu.
Ini juga berarti bahwa jika Anda pernah pergi dan jika orang lain mengambil alih Anda tidak akan memiliki utang teknis langsung karena tidak mendokumentasikan (melalui tes) apa yang melakukan apa.
Yang terpenting, "suatu hari" mungkin tidak akan datang. Anda bisa tertabrak bus atau Anda bisa naik bus untuk petualangan baru.
Akhirnya, pengujian manual tidak skala dan sering tidak mencakup semua perangkat yang digunakan oleh pengguna akhir.
sumber
Meskipun TDD sulit untuk menerapkan 100% ada kelemahan dalam pendekatan Anda
Menerapkan irisan kerja vertikal yang berfungsi
1,1 1 tahun berlalu ....
1.2 Pengembang baru mulai mengerjakan proyek
Jika irisan itu perlu modifikasi
2.3 Nama metode dan parameter gaya Parse 'Clean Coding' 'GetUnicorn (colourOfUnicorn)'
2.4 Baca xml komentar 'Mendapat unicorn emas (untuk berkuda) (obvs)'
2.5 Memburu dev asli
2.6 Semoga mereka ingat apa yang seharusnya dilakukan oleh kode
2.7 Minta mereka menjelaskan semuanya
Tulis Tes Unit, Tes Integrasi, Tes Perilaku, dll yang semoga menjamin potongan pekerjaan sudah benar
Saya pikir Anda benar untuk mengidentifikasi bahwa unit test benar-benar menunjukkan nilainya ketika modifikasi diperlukan.
sumber
Saya setuju dengan Daniel Hollinrake dan Ewan, bahwa poin kunci pertama mengapa tes-satunya-jika-modifikasi Anda berfungsi dengan baik sejauh ini adalah:
dan kemungkinan poin kunci kedua adalah:
Saya tidak berpikir TDD membawa peningkatan produktivitas besar untuk programmer tunggal, dan itu mungkin tidak sangat meningkatkan kualitas kode Anda jika Anda sudah menulis kode bersih yang baik.
Namun, TDD pasti akan meningkatkan kualitas kode programmer yang buruk / tidak berpengalaman / usang, terutama ketika tiba saatnya untuk memodifikasi kode tanpa merusak yang lain. Dan terlebih lagi jika orang yang memodifikasi kode tersebut bukan orang yang sama yang menulis kode itu semula atau beberapa bulan telah lewat di antaranya.
Dengan kata lain, saya pikir TDD adalah praktik yang baik untuk meningkatkan kualitas kode Anda (seperti yang Anda akui sendiri) tetapi juga (dan yang lebih penting) semacam lindung nilai ketika Anda bekerja dengan programmer rata-rata atau biasa-biasa saja (misalnya, dari departemen atau perusahaan lain) yang merupakan situasi yang jauh lebih umum daripada bekerja sendirian.
sumber
Bagi saya, kuncinya adalah:
Ini berfungsi untuk Anda dan Anda menghasilkan kode bersih yang bagus (saya berasumsi!). Satu-satunya hal yang saya katakan perlu Anda lakukan adalah membuat test harness sehingga pengembang lain dapat masuk dan percaya diri dalam melakukan perubahan. Harness pengujian memastikan konsistensi dalam perilaku kode.
Saya pikir pendekatan Anda mirip dengan pendekatan saya. Saya biasanya satu-satunya pengembang di proyek saya. Saya telah menemukan bahwa apresiasi TDD telah memungkinkan saya untuk menulis fungsi yang lebih kecil dan kode pembersih tetapi saya menambahkan tes sambil menulis kode sebagai test harness. Dengan begitu kode berkembang dan perubahan fungsionalitas saya dapat cukup percaya diri dalam membuat perubahan.
Alasan kedua untuk menulis tes adalah saya merasa itu adalah bentuk dokumentasi. Mereka dapat menjelaskan alasan saya di balik mengapa suatu fungsi dibuat. Tetapi di sini, saya lebih banyak berpikir tentang Pengembangan Berbasis Perilaku.
sumber
Unit Testing adalah tentang mengatasi masalah pemeliharaan kode. Meskipun ada orang yang mengatakan bahwa mereka lebih cepat menulis kode dengan TDD daripada tanpa, saya tidak terkejut bahwa Anda dapat menulis lebih banyak kode baru tanpa menulis tes.
Masalah yang dapat saya lihat dengan praktik tes menulis sebelum Anda mengubahnya:
Saya sering perlu membuat perubahan dengan tergesa-gesa
Meskipun Anda dapat menghemat waktu secara keseluruhan dengan hanya menulis tes saat Anda membutuhkannya, tidak semua waktu sama. Menghabiskan 2 jam menulis tes untuk menghemat 1 jam ketika saya dalam mode krisis - sangat berharga.
Lebih mudah menulis tes pada saat yang sama ketika saya menulis kode
Untuk menulis unit test dengan benar, Anda perlu memahami kode yang saya uji. Saya sering menggunakan pengujian unit sebagai latihan dalam pemahaman, tetapi pengujian unit kode yang ada dapat memakan waktu karena memahami kode yang ada memakan waktu. Kontras dengan menulis tes saat Anda menulis kode dan Anda akan menemukannya lebih cepat karena Anda sudah memahami kode - Anda baru saja menulisnya!
Definisi kode warisan Michael Feathers adalah kode tanpa tes. Terlepas dari apakah Anda setuju dengan definisinya, jelas bahwa sebagian besar biaya memodifikasi kode yang ada memastikan bahwa kode itu masih berfungsi seperti yang diharapkan, sering kali bahkan tidak jelas apa perilaku yang diharapkan.
Unit penulisan menguji offset yang harganya dengan menyandikan pemahaman tentang apa perilaku yang benar, serta memberikan cara mudah bagi "masa depan kita" untuk memeriksa bahwa perilaku itu masih benar.
sumber
Ini adalah pertanyaan yang bagus, dan FWIW saya akan memasukkan dua sen saya.
Sekitar setahun yang lalu saya menulis kode di Salesforce, sebuah platform yang memiliki mekanisme yang tertanam yang memaksa Anda untuk tidak perlu menulis tes sebelum Anda berkode , tetapi memaksa Anda untuk menulis tes secara umum.
Cara kerjanya adalah bahwa sistem akan memaksa Anda untuk menulis tes, dan itu akan membuat perhitungan jumlah baris kode Anda yang diuji dalam persentase. Jika semua kode di seluruh instance produksi Anda jatuh di bawah 75% diuji .. Salesforce tidak lagi bekerja.
Hasil akhirnya adalah setiap kali Anda melakukan sesuatu di Salesforce, Anda harus menulis atau memperbarui tes. Sementara saya yakin ini memiliki dampak besar pada pangsa pasar Salesforce, dalam hal kehidupan seorang pengembang itu adalah rasa sakit yang luar biasa di pantat .
Banyak kali Anda hanya mencoba melewati tiket kecil, dan kemudian pengujian masuk dan menggandakan waktu pengembangan Anda, untuk fitur yang Anda tahu berfungsi.
Kemudian konsep canggung TDD menyapu departemen kami, sampai ke basis data kami. Arsitek kami ingin mendorong pengujian menyeluruh ke setiap aspek departemen TI kami. Sedikit rasa sakit di pantat, bertemu rasa sakit yang lebih besar di pantat.
Dulu TDD tidak pernah benar-benar masuk akal bagi saya, dan bahkan sekarang masih tidak. Banyak fungsi yang saya tulis dalam peran saya saat ini terjadi dalam mekanisme yang mirip dengan yang telah Anda sebutkan: dalam irisan vertikal yang saya sempurnakan sampai berfungsi. Ketika saya berada di peran lama itu, dan masih sekarang saya sering tidak tahu apa kode saya akan lakukan sampai saya benar-benar menulisnya , sehingga gagasan bahwa saya dapat menulis tes untuk mendorong kode saya akan menulis saja. Tidak masuk akal bagi saya, rumit, dan kebanyakan hanya buang-buang waktu.
Semua itu mengatakan, ujian adalah hal-hal yang luar biasa dan ajaib yang membuat segalanya menjadi benar di dunia . Mereka membuat kode Anda benar, mereka memastikan aplikasi Anda melakukan apa yang Anda pikirkan, dan umumnya semuanya lebih lancar. Pertanyaannya kemudian bukan apakah Anda menulis tes Anda sebelum kode, atau setelah kode Anda, pertanyaannya adalah berapa lama Anda akan berkomitmen untuk pengujian. Itulah masalah sebenarnya, setidaknya dalam pengalaman pengembangan perangkat lunak saya. Pengujian membutuhkan waktu dan uang dan Anda harus melakukannya dalam kerangka minat yang bersaing.
Jadi, secara umum saya setuju dengan Anda: TDD dalam praktiknya agak canggung dan rumit. Pada titik itu Anda perlu mengingat apa yang paling berhasil dalam situasi Anda saat ini . Jika Anda menulis kode kritis, pastikan itu diuji secara umum. Jika Anda punya waktu, coba TDD dan lihat apakah itu menambah sesuatu pada proses.
sumber
Saya tidak bisa merekomendasikan pendekatan Anda.
Jika saya menggunakan pendekatan Anda itu akan menjadi seperti contoh berikut (rumah adalah aplikasi):
Jadi pendekatan Anda menghabiskan banyak waktu dan banyak pengetahuan sebelum saya membangun rumah dengan pendekatan Anda. Atau butuh banyak waktu! Juga tidak cukup Gentleman untuk membiarkan tes tulis lain untuk kode Anda ketika ada persyaratan telah berubah.
Jadi ada pendekatan yang lebih baik tanpa pemrograman "prototipe" dan daripada mulai refactoring. Alih-alih memprogram prototipe "buat Desain dengan UML Aplikasi Anda sebagai berikut.
Tentu pendekatan ini juga membutuhkan beberapa Pengetahuan di UML tetapi cepat dipelajari. Dan itu selalu lebih cepat untuk mengubah nama Kelas atau memindahkan panah dalam digram daripada melakukannya di IDE Anda. Tetapi mempelajari penggunaan kerangka uji akan lebih melelahkan di awal. Yang terbaik adalah di sini untuk melihat uji coba proyek sumber terbuka dan lihat bagaimana mereka bekerja. Tetapi ketika Anda ave aplikasi tes didorong aplikasi berikutnya akan jauh lebih cepat. Dan saya pikir itu perasaan yang baik untuk mengetahui semuanya bekerja dengan baik.
Jadi saya hanya memilih pendekatan karena mereka sangat memakan waktu untuk pemula dan tidak baik. Untuk memiliki batas bersih antara struktur dan perilaku Anda, Anda dapat menggunakan Desain yang digerakkan domain dan di bawah Atur Domain dengan dua Paket (satu paket bernama struktur dan perilaku bernama lainnya). Juga untuk tes Anda. contoh sederhana lihat Contoh ini ditulis dalam java.
sumber
Apakah Anda menguji secara manual setiap kemungkinan cabang kondisi Anda setelah sedikit perubahan? Berapa lama waktu yang diperlukan untuk pengulangan umpan balik dari pengujian manual Anda. Seberapa dekat dengan loop umpan balik yang Anda dapatkan dengan tes otomatis.
Tes otomatis (tidak masalah tes-pertama atau tidak) membuat Anda cepat - dengan memberikan umpan balik yang lebih cepat pada kode Anda.
Apakah Anda yakin akan ingat untuk menguji beberapa kondisi secara manual setelah enam bulan - jangan katakan Anda akan mendokumentasikan semua kondisi penting untuk diuji - karena penulisan jenis dokumentasi / komentar sama dengan tes menulis (dokumentasi yang dapat dieksekusi)
Dan lagi: sementara refactoring apakah Anda secara manual menguji semua logika yang terpengaruh oleh refactoring? Berapa lama waktu untuk menguji perubahan refactoring? Jika refactoring memecahkan beberapa kode, berapa lama Anda menemukan alasan untuk istirahat?
Kode cantik dan bersih yang Anda nikmati sangat subjektif. Kode Anda bisa bersih dan masuk akal untuk Anda. Metode terbaik untuk memeriksa apakah kode Anda benar-benar dapat dibaca, dimengerti, dan dapat diuji, adalah pengujian dan ulasan kode yang dibuat oleh pengembang lain.
Anda menemukan cara Anda sangat produktif hanya karena Anda hanya pengembang yang bekerja dengan kode, dan, saya pikir, karena Anda baru mulai bekerja di proyek ini (Berapa usia proyek yang Anda kerjakan ini? 6 - 8 bulan?).
Anda masih ingat semua yang Anda tulis dan Anda bisa mengenali alasan untuk masalah yang mungkin terjadi. Saya cukup yakin Anda akan mulai menulis tes dari awal setelah 2 - 3 tahun proyek Anda - karena Anda ingin memastikan bahwa Anda tidak melupakan apa pun.
sumber
Jika Anda tidak pernah melakukan kesalahan, Anda tidak benar-benar membutuhkan tes. Kebanyakan pengembang memang melakukan kesalahan, tetapi jika Anda tidak pernah melakukannya, dan Anda yakin Anda tidak akan pernah membuat kesalahan di masa depan (dan Anda adalah satu-satunya di proyek), benar-benar tidak ada alasan untuk membuang waktu menulis tes.
Tetapi solusi Anda agak setengah karena Anda mengusulkan untuk menulis tes ketika mengubah kode, tetapi pada saat yang sama metode Anda mengasumsikan bahwa Anda tidak akan pernah membuat kesalahan ketika Anda memutuskan bagian mana dari kode untuk menulis tes. Ini hanya berfungsi jika Anda selalu memahami dengan sempurna bidang mana yang dapat memengaruhi perubahan. Saya pikir banyak pengembang umum (bukan Anda tentu saja!) Telah mengalami perubahan, dan kemudian pengujian di suatu tempat yang tidak terduga gagal, karena Anda membuat kesalahan.
Tentu saja arsitektur yang baik, prinsip SOLID dll. Harus mencegah hal ini terjadi, tetapi sebagian besar pengembang tidak sempurna, dan inilah sebabnya pengujian di seluruh sistem sangat berharga.
sumber