Saya saat ini refactoring bagian dari basis kode besar tanpa unit test apa pun. Saya mencoba untuk memperbaiki kode dengan cara kasar, yaitu dengan mencoba menebak apa yang dilakukan kode dan perubahan apa yang tidak akan mengubah artinya, tetapi tanpa hasil: secara acak memecah fitur-fitur di sekitar basis kode.
Perhatikan bahwa refactoring mencakup pemindahan kode C # lama ke gaya yang lebih fungsional (kode lama tidak menggunakan salah satu fitur .NET Framework 3 dan yang lebih baru, termasuk LINQ), menambahkan generik di mana kode dapat mengambil manfaat darinya, dll.
Saya tidak dapat menggunakan metode formal , mengingat berapa biayanya.
Di sisi lain, saya berasumsi bahwa setidaknya "Setiap kode warisan refactored harus datang dengan unit test" harus diikuti dengan ketat, tidak peduli berapa biayanya. Masalahnya adalah ketika saya memperbaiki sebagian kecil metode pribadi 500 LOC, menambahkan tes unit tampaknya menjadi tugas yang sulit.
Apa yang bisa membantu saya mengetahui unit test mana yang relevan untuk bagian kode tertentu? Saya menduga bahwa analisis statis dari kode akan membantu, tetapi apa alat dan teknik yang dapat saya gunakan untuk:
Tahu persis tes unit apa yang harus saya buat,
Dan / atau tahu jika perubahan yang saya lakukan memengaruhi kode asli dengan cara yang dieksekusi berbeda dari sekarang?
sumber
formal methods in software development
karena itu digunakan untuk membuktikan kebenaran suatu program menggunakan logika predikat dan tidak akan memiliki penerapan untuk refactoring basis kode besar. Metode formal biasanya digunakan untuk membuktikan kode bekerja dengan benar di bidang-bidang seperti aplikasi medis. Anda benar itu mahal untuk melakukan itu sebabnya itu tidak sering digunakan.Jawaban:
Saya memiliki tantangan serupa. Buku Bekerja dengan Kode Legacy adalah sumber yang bagus, tetapi ada asumsi bahwa Anda dapat menggunakan tes unit untuk mendukung pekerjaan Anda. Terkadang itu tidak mungkin.
Dalam pekerjaan arkeologi saya (istilah saya untuk pemeliharaan kode warisan seperti ini), saya mengikuti pendekatan yang sama dengan apa yang Anda uraikan.
Pada titik ini, Anda harus memiliki daftar kandidat tentang apa yang telah diekspos dan / atau dimanipulasi oleh rutinitas itu. Beberapa dari manipulasi itu kemungkinan besar tidak disengaja. Sekarang saya menggunakan
findstr
dan IDE untuk memahami area apa yang mungkin mereferensikan item dalam daftar kandidat. Saya akan meluangkan waktu untuk memahami bagaimana referensi itu bekerja dan apa sifatnya.Akhirnya, setelah saya menipu diri sendiri untuk berpikir bahwa saya memahami dampak dari rutinitas asli, saya akan melakukan perubahan saya satu per satu dan menjalankan kembali langkah analisis yang saya uraikan di atas untuk memverifikasi bahwa perubahan itu berfungsi seperti yang saya harapkan itu bekerja. Saya secara khusus mencoba untuk menghindari mengubah banyak hal sekaligus karena saya menemukan ini meledak pada saya ketika saya mencoba dan memverifikasi dampaknya. Kadang-kadang Anda bisa lolos dengan beberapa perubahan, tetapi jika saya bisa mengikuti rute satu per satu, itu adalah pilihan saya.
Singkatnya, pendekatan saya mirip dengan apa yang Anda paparkan. Ini banyak pekerjaan persiapan; kemudian berhati-hati, perubahan individu; dan kemudian memverifikasi, memverifikasi, memverifikasi.
sumber
Jawaban singkat: langkah kecil.
Pertimbangkan langkah-langkah ini:
Pindahkan implementasi ke fungsi (pribadi) yang berbeda dan delegasikan panggilan.
Tambahkan kode logging (pastikan logging tidak gagal) di fungsi asli Anda, untuk semua input dan output.
Jalankan aplikasi Anda dan lakukan apa pun yang Anda bisa dengannya (penggunaan yang valid, penggunaan yang tidak valid, penggunaan tipikal, penggunaan yang tidak biasa, dll).
Anda sekarang memiliki
max(call_count)
set input dan output untuk menulis tes Anda dengan; Anda bisa menulis satu tes yang mengulang semua set parameter / hasil yang Anda miliki dan menjalankannya dalam satu lingkaran. Anda juga dapat menulis tes tambahan yang menjalankan kombinasi tertentu (untuk digunakan untuk memeriksa dengan cepat melewati set i / o tertentu).Pindah
// 500 LOC here
kembali keugly500loc
fungsi Anda (dan hapus fungsionalitas logging).Mulai mengekstraksi fungsi dari fungsi besar (tidak melakukan apa-apa lagi, cukup ekstrak fungsi) dan jalankan tes. Setelah ini, Anda harus memiliki lebih sedikit fungsi untuk refactor, daripada fungsi 500LOC.
Hidup bahagia selamanya.
sumber
Biasanya Tes Unit adalah cara yang harus dilakukan.
Buat tes yang diperlukan yang membuktikan bahwa saat ini berfungsi seperti yang diharapkan. Luangkan waktu Anda dan tes terakhir harus membuat Anda percaya diri pada hasilnya.
Anda sedang dalam proses refactoring sepotong kode, Anda harus tahu persis apa yang dilakukannya dan apa dampaknya. Jadi pada dasarnya Anda perlu menguji semua zona yang terkena dampak. Ini akan membawa Anda banyak waktu ... tapi itu hasil yang diharapkan dari setiap proses refactoring.
Kemudian Anda dapat memisahkan semuanya tanpa masalah.
AFAIK, tidak ada teknik anti peluru untuk ini ... Anda hanya perlu metodis (pada metode apa pun Anda merasa nyaman), banyak waktu dan banyak kesabaran! :)
Ceria dan semoga berhasil!
Alex
sumber