Saya bekerja di perusahaan kecil sebagai pengembang solo. Sebenarnya saya satu-satunya pengembang di perusahaan itu. Saya memiliki beberapa (relatif) proyek besar yang telah saya tulis dan kelola secara teratur, dan tidak satu pun dari mereka memiliki tes untuk mendukungnya. Ketika saya memulai proyek baru, saya sering bertanya-tanya apakah saya harus mencoba pendekatan TDD. Kedengarannya seperti ide yang bagus, tapi jujur saya tidak pernah bisa membenarkan kerja ekstra yang terlibat.
Saya bekerja keras untuk berpikiran maju dalam desain saya. Saya menyadari bahwa suatu hari nanti pengembang lain harus menjaga kode saya, atau paling tidak memecahkannya. Saya menjaga hal-hal sesederhana mungkin dan saya berkomentar dan mendokumentasikan hal-hal yang sulit untuk dipahami. Dan faktanya adalah proyek-proyek ini tidak begitu besar atau rumit sehingga pengembang yang layak akan berjuang untuk memahaminya.
Banyak contoh yang saya lihat dari tes sampai ke hal-hal kecil, yang mencakup semua aspek kode. Karena saya adalah satu-satunya pengembang dan saya sangat dekat dengan kode di seluruh proyek, jauh lebih efisien untuk mengikuti pola tulis-kemudian-secara manual-tes. Saya juga menemukan persyaratan dan fitur berubah cukup sering sehingga mempertahankan tes akan menambah jumlah hambatan pada suatu proyek. Waktu itu kalau tidak bisa dihabiskan untuk menyelesaikan kebutuhan bisnis.
Jadi saya berakhir dengan kesimpulan yang sama setiap kali. Pengembalian investasi terlalu rendah.
Saya kadang-kadang menyiapkan beberapa tes untuk memastikan saya telah menulis algoritma dengan benar, seperti menghitung berapa tahun seseorang telah berada di perusahaan berdasarkan tanggal perekrutan mereka. Tetapi dari sudut pandang cakupan kode saya telah membahas sekitar 1% dari kode saya.
Dalam situasi saya, apakah Anda masih menemukan cara untuk membuat unit menguji praktik biasa, atau apakah saya dibenarkan untuk menghindari overhead itu?
UPDATE: Beberapa hal tentang situasi saya yang saya tinggalkan: Proyek saya adalah semua aplikasi web. Untuk mencakup semua kode saya, saya harus menggunakan tes UI otomatis, dan itu adalah area di mana saya masih tidak melihat manfaat besar dibandingkan pengujian manual.
sumber
Jawaban:
Begitu? Anda tidak perlu menguji semuanya . Hanya hal-hal yang relevan.
Itu sebenarnya salah. Itu tidak lebih efisien. Ini benar-benar hanya kebiasaan.
Apa yang dilakukan pengembang solo lain adalah menulis sketsa atau garis besar, menulis kasus uji, lalu mengisi garis besar dengan kode akhir.
Itu sangat, sangat efisien.
Itu juga salah. Tes bukan hambatan. Perubahan persyaratan adalah hambatan.
Anda harus memperbaiki tes untuk mencerminkan persyaratan. Apakah hal-hal kecil mereka, atau tingkat tinggi; ditulis pertama atau terakhir ditulis.
Kode tidak selesai sampai tes berlalu. Itulah satu kebenaran universal perangkat lunak.
Anda dapat memiliki tes penerimaan terbatas "ini dia".
Atau Anda dapat melakukan beberapa tes unit.
Atau Anda dapat memiliki keduanya.
Tapi apa pun yang Anda lakukan, selalu ada tes untuk menunjukkan bahwa perangkat lunak itu berfungsi.
Saya akan menyarankan bahwa sedikit formalitas dan rangkaian alat uji unit yang bagus membuat tes itu jauh lebih berguna.
sumber
sqrt(-1)
harus bilangan bulat, Anda akan mendapatkan respons luar biasa dengan satu arah. Keseimbangan adalah sekitar "bagaimana" dan "urutan apa". Fakta sebenarnya adalah bahwa Anda harus menguji. Jadi, tulis dulu tesnya dan pastikan semuanya bekerja.Bayangkan Anda memiliki serangkaian tes yang dapat berjalan di eyeblink dan akan menyala lampu hijau atau merah. Bayangkan bahwa rangkaian tes ini menguji semuanya ! Bayangkan yang harus Anda lakukan untuk menjalankan serangkaian tes adalah mengetikkan ^ T. Kekuatan apa yang akan memberimu ini?
Bisakah Anda membuat perubahan pada kode tanpa takut merusak sesuatu? Bisakah Anda menambahkan fitur baru tanpa takut merusak fitur lama? Bisakah Anda membersihkan kode berantakan dengan cepat tanpa takut melakukan kerusakan?
Ya, Anda bisa melakukan semua itu! Dan apa yang akan terjadi pada kode Anda dari waktu ke waktu? Itu akan menjadi lebih bersih dan bersih karena tidak akan ada risiko untuk membersihkannya.
Mari kita bayangkan bahwa Anda memiliki peri kecil di bahu Anda. Setiap kali Anda menulis satu baris kode, peri akan menambahkan sesuatu ke suite tes yang menguji bahwa baris kode itu melakukan apa yang seharusnya dilakukan. Jadi setiap beberapa detik Anda dapat menekan ^ T dan melihat bahwa baris kode terakhir yang Anda tulis berhasil.
Berapa banyak debug yang menurut Anda akan Anda lakukan?
Jika ini kedengarannya seperti fantasi, Anda benar. Namun kenyataannya tidak jauh berbeda. Ganti eyeblink dengan beberapa detik, dan peri dengan disiplin TDD, dan Anda sudah cukup banyak mendapatkannya.
Katakanlah Anda kembali ke sistem yang Anda buat setahun lalu, dan Anda lupa cara membuat salah satu objek utama. Ada tes yang membuat objek itu setiap cara dapat dibuat. Anda dapat membaca tes-tes itu dan menyiarkan memori Anda. Perlu menelepon API? Ada tes yang memanggil API itu setiap cara dapat dipanggil. Tes-tes ini adalah dokumen - dokumen kecil , ditulis dalam bahasa yang Anda mengerti. Mereka sama sekali tidak ambigu. Mereka begitu formal sehingga mereka mengeksekusi. Dan mereka tidak dapat keluar dari sinkronisasi dengan aplikasi!
Tidak layak investasi? Anda pasti bercanda! Bagaimana mungkin ada orang yang TIDAK menginginkan rangkaian tes itu? Bantulah diri Anda sendiri dan berhentilah berdebat dengan kekonyolan. Belajarlah untuk melakukan TDD dengan baik, dan perhatikan seberapa cepat Anda melangkah, dan seberapa bersih kode Anda.
sumber
Kesalahan yang Anda buat adalah bahwa Anda melihat pengujian sebagai investasi waktu tanpa pengembalian segera. Tidak harus seperti itu.
Tes menulis pertama benar-benar memfokuskan Anda pada apa yang perlu dilakukan bagian kode ini.
Menjalankan keduanya mengungkapkan bug yang seharusnya muncul dalam pengujian.
Menjalankan ketiga terkadang menunjukkan bug yang tidak akan muncul dalam pengujian dan kemudian akan benar-benar menggigit Anda dalam produksi.
Keempat jika Anda menekan bug dengan sistem yang sedang berjalan dan membuat unit test untuknya, Anda tidak akan bisa memperkenalkan kembali bug itu nanti. Itu bisa sangat membantu. Bug yang diperkenalkan kembali adalah hal yang umum dan sangat mengganggu.
Kelima, jika Anda perlu menyerahkan kode kepada orang lain, test suite akan membuat hidup mereka jauh lebih mudah. Juga jika Anda telah mengabaikan proyek dan kembali ke sana setelah beberapa tahun, Anda tidak akan begitu dekat dengan itu lagi dan itu akan membantu Anda juga.
Pengalaman saya secara konsisten adalah bahwa dalam pengembangan proyek, memiliki unit test yang layak selalu membuat proses lebih cepat dan lebih dapat diandalkan.
sumber
Orang-orang di JUnit (kerangka uji Java Unit) memiliki filosofi bahwa jika terlalu mudah untuk diuji, jangan mengujinya . Saya sangat merekomendasikan membaca FAQ Praktik Terbaik mereka , karena cukup pragmatis.
TDD adalah proses penulisan perangkat lunak Anda yang berbeda. Premis dasar di balik pengujian unit adalah bahwa Anda akan menghabiskan lebih sedikit waktu dalam debugger melangkah melalui kode, dan lebih cepat mencari tahu apakah perubahan kode Anda secara tidak sengaja merusak sesuatu yang lain dalam sistem. Itu cocok dengan TDD. Siklus TDD seperti ini:
Apa yang kurang jelas tentang penerapan TDD adalah bahwa ia mengubah cara penulisan kode Anda . Dengan memaksa diri Anda berpikir tentang cara menguji / memvalidasi bahwa kode berfungsi, Anda menulis kode yang dapat diuji. Dan karena kita berbicara pengujian unit, itu biasanya berarti bahwa kode Anda menjadi lebih modular. Bagi saya, kode modular dan dapat diuji adalah kemenangan besar di depan.
Sekarang, apakah Anda perlu menguji hal-hal seperti properti C #? Bayangkan sebuah properti didefinisikan seperti ini:
Jawabannya adalah "tidak", ini tidak layak untuk diuji, karena pada titik ini Anda menguji fitur bahasa. Hanya percaya bahwa platform C # orang benar. Selain itu, jika gagal, apa yang bisa Anda lakukan untuk memperbaikinya?
Juga, Anda akan menemukan bahwa ada bagian-bagian tertentu dari kode Anda yang sangat baik akan terlalu banyak upaya untuk menguji dengan benar. Itu berarti jangan lakukan itu, tetapi pastikan Anda menguji kode yang menggunakan / digunakan oleh masalah rumit:
Percaya atau tidak, TDD akan membantu Anda jatuh ke dalam laju pembangunan berkelanjutan. Ini bukan karena sihir, melainkan karena Anda memiliki umpan balik yang ketat dan Anda dapat menangkap kesalahan yang sangat bodoh dengan cepat. Biaya untuk memperbaiki kesalahan tersebut pada dasarnya adalah konstan (setidaknya cukup untuk tujuan perencanaan) karena kesalahan kecil tidak pernah tumbuh menjadi kesalahan besar. Bandingkan dengan sifat sprint kode pesta / debug purge sprint.
sumber
Anda harus menyeimbangkan biaya pengujian dengan biaya bug.
Menulis tes unit 10 baris untuk fungsi yang membuka file, di mana kegagalannya adalah "file tidak ditemukan" tidak ada gunanya.
Fungsi yang melakukan sesuatu yang kompleks pada struktur data yang kompleks - maka jelas ya.
Agak sulit ada di antara keduanya. Tapi ingat nilai sebenarnya dari unit test tidak menguji fungsi tertentu, itu menguji interaksi rumit di antara mereka. Jadi tes unit yang melihat bahwa perubahan dalam satu bit kode, memecah beberapa fungsi dalam modul yang berbeda 1000 baris jauhnya, bernilai berat dalam kopi.
sumber
Pengujian adalah judi.
Membuat tes adalah bertaruh bahwa biaya bug dalam unit terjadi dan tidak menangkap mereka dengan tes itu (sekarang, dan selama semua revisi kode masa depan) lebih besar daripada biaya pengembangan tes. Biaya pengembangan pengujian tersebut mencakup hal-hal seperti penggajian untuk rekayasa pengujian tambahan, penambahan waktu ke pasar, biaya peluang yang hilang karena tidak mengkode hal-hal lain, dan sebagainya.
Seperti taruhan apa pun, terkadang Anda menang, terkadang Anda kalah.
Kadang-kadang perangkat lunak terlambat dengan bug jauh lebih sedikit menang atas hal-hal cepat tapi buggy yang sampai ke pasar terlebih dahulu. Terkadang sebaliknya. Anda harus melihat statistik di bidang khusus Anda, dan seberapa banyak manajemen ingin bertaruh.
Beberapa jenis bug mungkin sangat tidak mungkin dibuat, atau berhasil keluar dari pengujian kewarasan awal, sehingga secara statistik tidak sepadan dengan waktu untuk membuat tes khusus tambahan. Tetapi kadang-kadang biaya bug sangat besar (medis, nuklir, dll) sehingga perusahaan harus mengambil taruhan yang kalah (mirip dengan membeli asuransi). Banyak aplikasi tidak memiliki biaya kegagalan yang tinggi, dan karenanya tidak memerlukan perlindungan asuransi yang tidak ekonomis. Yang lainnya melakukannya.
sumber
Saran saya adalah hanya menguji kode yang Anda ingin berfungsi dengan benar.
Jangan menguji kode yang Anda ingin menjadi buggy dan menyebabkan masalah bagi Anda di jalan.
sumber
TDD dan Unit Testing bukan hal yang sama.
Anda dapat menulis kode, lalu menambahkan unit test nanti. Itu bukan TDD, dan banyak pekerjaan tambahan.
TDD adalah praktik pengkodean dalam satu lingkaran Lampu Merah. Lampu hijau. Iterasi refactor.
Ini berarti menulis tes untuk kode yang belum ada, menonton tes gagal, memperbaiki kode untuk membuat tes bekerja, kemudian membuat kode "benar". Ini sering menghemat pekerjaan Anda
Salah satu kelebihan TDD adalah mengurangi kebutuhan untuk memikirkan hal-hal sepele. Hal-hal seperti kesalahan satu demi satu menghilang. Anda tidak harus mencari melalui dokumentasi API untuk mengetahui apakah daftar yang dikembalikan dimulai dari 0 atau 1, lakukan saja.
sumber
Saya bekerja pada sistem di mana kami menguji hampir semuanya. Eksekusi penting untuk pengujian adalah kode output PDF dan XLS.
Mengapa? Kami dapat menguji bagian-bagian yang mengumpulkan data dan membangun model yang digunakan untuk membuat output. Kami juga dapat menguji bagian-bagian yang menemukan bagian model mana yang akan digunakan untuk file PDF. Kami tidak dapat menguji apakah PDF tampak baik karena itu benar-benar subjektif. Kami tidak dapat menguji apakah semua bagian dalam PDF dapat dibaca oleh pengguna biasa karena itu juga subjektif. Atau jika pilihan antara diagram batang dan pai benar untuk dataset.
Jika output akan menjadi subyektif, ada sedikit pengujian unit yang dapat Anda lakukan sepadan dengan usaha.
sumber
Untuk banyak hal, 'tes-kemudian-manual-tes' tidak membutuhkan waktu lebih lama daripada menulis beberapa tes. Penghematan waktu berasal dari kemampuan untuk menjalankan kembali tes tersebut kapan saja.
Anggap saja: Jika Anda memiliki beberapa cakupan fitur yang layak dengan tes Anda (tidak harus bingung dengan cakupan kode), dan katakanlah Anda memiliki 10 fitur - mengklik sebuah tombol berarti Anda memiliki kira-kira, 10 kasih kembali melakukan tes Anda ... sementara Anda duduk dan menyesap kopi Anda.
Anda juga tidak perlu menguji minutae. Anda dapat menulis tes integrasi yang mencakup fitur-fitur Anda jika Anda tidak ingin turun ke detail yang rumit ... IMO, beberapa unit test terlalu halus menguji bahasa dan platform, dan bukan kode.
TL; DR Ini benar-benar tidak pernah tepat karena manfaatnya terlalu bagus.
sumber
Dua jawaban yang sangat baik yang saya temui ada di sini:
Pembenaran untuk menghindari persepsi overhead:
Apakah Anda tidak ingin meninggalkan produk hebat dari sisi Anda sebagai bukti kualitas pekerjaan Anda? Berbicara dengan sikap egois, bukankah lebih baik bagimu daripada kamu?
sumber
Pengembang profesional menulis unit test karena, dalam jangka panjang, mereka menghemat waktu. Anda akan menguji kode Anda cepat atau lambat, dan jika Anda tidak melakukannya, maka jika Anda harus memperbaiki bug, mereka akan lebih sulit untuk memperbaikinya dan lebih banyak mengetuk efek.
Jika Anda menulis kode tanpa tes dan tanpa bug maka baik-baik saja. Saya tidak percaya Anda dapat menulis sistem non-sepele dengan nol bug, jadi saya berasumsi Anda sedang menguji satu atau lain cara.
Tes unit juga penting untuk mencegah regresi ketika Anda memodifikasi atau memperbaiki kode lama. Mereka tidak membuktikan perubahan Anda tidak merusak kode lama tetapi mereka memberi Anda banyak kepercayaan (selama mereka lulus tentu saja :))
Saya tidak akan kembali dan menulis seluruh tes untuk kode yang sudah Anda kirim, tetapi lain kali Anda perlu memodifikasi fitur yang saya sarankan untuk mencoba menulis tes untuk modul atau kelas itu, dapatkan cakupan Anda hingga 70% + sebelum Anda menerapkan perubahan apa pun. Lihat apakah itu membantu Anda.
Jika Anda mencobanya dan dapat dengan jujur mengatakan itu tidak membantu maka cukup adil, tetapi saya pikir ada cukup bukti industri yang mereka bantu untuk membuatnya setidaknya layak untuk Anda saat menguji coba pendekatan.
sumber
Sepertinya sebagian besar jawaban adalah pro-TDD, meskipun pertanyaannya bukan tentang TDD tetapi tentang tes unit secara umum.
Tidak ada aturan yang sepenuhnya objektif di balik apa yang harus diuji unit atau tidak untuk tes unit. Tetapi ada beberapa kali di mana tampaknya banyak programmer tidak menguji unit:
Bergantung pada filosofi OOP Anda, Anda dapat membuat metode pribadi untuk memisahkan rutinitas kompleks dari metode publik Anda. Metode publik biasanya dimaksudkan untuk dipanggil di banyak tempat yang berbeda dan sering digunakan, dan metode pribadi hanya benar-benar dipanggil oleh satu atau dua metode publik di kelas atau modul untuk sesuatu yang sangat spesifik. Biasanya cukup untuk menulis unit test untuk metode publik tetapi bukan metode pribadi yang mendasari yang membuat beberapa keajaiban terjadi. Jika ada yang salah dengan metode pribadi, tes unit metode publik Anda harus cukup baik untuk mendeteksi masalah ini.
Banyak programmer baru menentang ini ketika mereka pertama kali belajar untuk menguji, dan berpikir bahwa mereka perlu menguji setiap baris yang dieksekusi. Jika Anda menggunakan perpustakaan eksternal dan fungsinya diuji dan didokumentasikan dengan baik oleh penulisnya, biasanya tidak ada gunanya menguji fungsionalitas khusus dalam pengujian unit. Misalnya, seseorang mungkin menulis tes untuk memastikan bahwa model ActiveRecord mereka tetap memiliki nilai yang benar untuk atribut dengan callback "before_save" ke database, meskipun perilaku itu sendiri sudah diuji secara menyeluruh di Rails. Metode yang dipanggil oleh panggilan balik, mungkin, tetapi bukan perilaku panggilan balik itu sendiri. Setiap masalah mendasar dengan perpustakaan yang diimpor akan lebih baik terungkap melalui tes penerimaan, daripada tes unit.
Keduanya bisa berlaku apakah Anda sedang melakukan TDD atau tidak.
sumber
Ken, saya dan banyak pengembang lain di luar sana telah sampai pada kesimpulan yang sama seperti Anda beberapa kali sepanjang karier kami.
Kebenaran yang saya yakin akan Anda temukan (seperti yang lainnya) adalah bahwa investasi awal tes menulis untuk aplikasi Anda mungkin tampak menakutkan, tetapi jika ditulis dengan baik dan ditargetkan pada bagian kode yang benar, mereka benar-benar dapat menghemat satu ton waktu.
Masalah besar saya adalah dengan kerangka pengujian yang tersedia. Saya tidak pernah benar-benar merasa seperti itu yang saya cari, jadi saya hanya menggulung solusi saya yang sangat sederhana. Ini benar-benar membantu membawa saya ke "sisi gelap" pengujian regresi. Saya akan membagikan cuplikan pseudo dasar dari apa yang saya lakukan di sini, dan mudah-mudahan Anda dapat menemukan solusi yang cocok untuk Anda.
Satu-satunya bagian yang sulit setelah itu adalah mencari tahu tingkat granularitas apa yang Anda pikirkan adalah yang terbaik untuk proyek apa pun yang Anda lakukan.
Membangun buku alamat akan sangat membutuhkan pengujian jauh lebih sedikit daripada mesin pencari perusahaan, tetapi dasarnya tidak benar-benar berubah.
Semoga berhasil!
sumber