Meneruskan
Saya sudah membaca banyak hal sebelum mengajukan pertanyaan ini, termasuk banyak pertanyaan yang relevan di sini di SE:
- (Rekayasa Perangkat Lunak SE) Menulis tes untuk kode yang tujuannya tidak saya mengerti
- (Rekayasa Perangkat Lunak SE) Unit pengujian tim pemula perlu pengujian unit
- (Rekayasa Perangkat Lunak SE) Praktik terbaik untuk perkuatan kode lama dengan tes otomatis
- (Rekayasa Perangkat Lunak SE) Bagaimana cara menguji sistem warisan yang besar?
- (Posting blog) Cara meniru lingkungan Unit Test Anda
Namun, saya merasa gatal belum tergores setelah membaca untuk bantuan.
TL; DR
Bagaimana cara menulis unit test untuk kode lawas yang tidak dapat saya jalankan, simulasi, baca, atau mudah dimengerti? Tes regresi apa yang berguna untuk komponen yang mungkin berfungsi seperti yang dimaksudkan?
Keseluruhan gambar
Saya magang musim panas yang kembali lagi saat saya beralih ke sekolah pascasarjana. Penugasan saya melibatkan persyaratan ini:
- Untuk produk tertentu, evaluasi apakah tim perangkat lunak kami dapat meningkatkan versi IDE dan JUnit mereka tanpa kehilangan kompatibilitas dengan proyek yang ada.
- Kembangkan tes unit untuk beberapa komponen dalam kode Java yang ada (sebagian besar bukan Java). Kami ingin meyakinkan tim perangkat lunak bahwa pengujian unit dan TDD adalah alat yang sangat berharga yang harus mereka gunakan. (Saat ini ada cakupan kode 0%.)
- Entah bagaimana, akhiri hari-hari pengkodean koboi untuk sistem kritis.
Setelah mendapatkan salinan kode sumber, saya mencoba membangun dan menjalankannya, sehingga saya bisa mengerti apa yang dilakukan produk ini dan bagaimana cara kerjanya. Saya tidak bisa. Saya bertanya kepada penyelia saya bagaimana saya melakukannya, dan saya diberi mesin mandiri baru yang mampu membangunnya, termasuk skrip pembuatan yang sebenarnya. Itu tidak berhasil karena seperti yang seharusnya, kode produksi mereka hanya berjalan pada sistem embedded yang dirancang untuknya. Namun, mereka memiliki simulator untuk tujuan ini, jadi mereka memperoleh simulator dan menaruhnya di mesin ini untuk saya. Simulator juga tidak berfungsi. Sebagai gantinya, saya akhirnya menerima cetakan GUI untuk layar tertentu. Mereka juga tidak memiliki komentar kode di mana pun dalam 700.000+ Java LOC, membuatnya semakin sulit untuk dipahami. Selanjutnya, ada masalah yang mengevaluasi apakah proyek mereka kompatibel dengan IDE yang lebih baru atau tidak. Khususnya, kode mereka tidak dimuat dengan benar ke dalam versi IDE yang mereka gunakan.
Inventaris saya terlihat seperti ini:
- NetBeans 8, 9, 10, 11
- JUnit 4, 5
- Kode sumber mereka untuk produk tertentu (termasuk 700.000+ Java LOC)
- Hampir tidak ada komentar kode (terkadang tanda tangan)
- Tidak ada tes yang ada
- Foto fisik jendela GUI
- Dokumen desain perangkat lunak (109 hal.) Yang tidak membahas komponen dalam gambar
Saya setidaknya memiliki cukup untuk secara teoritis menulis tes yang dapat dijalankan. Jadi, saya mencoba unit test dasar pada komponen ini. Namun, saya tidak bisa menginisialisasi objek yang ia miliki sebagai dependensi, yang mencakup model, manajer, dan koneksi DB. Saya tidak memiliki banyak pengalaman JUnit di luar pengujian unit dasar, jadi ikuti saya ke bagian selanjutnya.
Apa yang Saya Pelajari dari Membaca Saya
- Mengolok-olok: Jika saya menulis unit test, kemungkinan perlu memiliki variabel tiruan untuk dependensi produksi yang saya tidak dapat dengan mudah menginisialisasi
setUp
. - Semua orang di sini dengan bebas menyarankan buku "Bekerja Efektif dengan Kode Legacy" oleh Michael Feathers.
- Tes regresi mungkin merupakan tempat yang baik untuk memulai. Saya tidak berpikir saya memiliki cukup senjata untuk mencoba pengujian integrasi, dan tes regresi akan memberikan kepuasan lebih instan kepada tim perangkat lunak kami. Namun, saya tidak memiliki akses ke bug yang dikenal; tapi, aku mungkin bisa bertanya.
Dan sekarang upaya untuk mengartikulasikan ketidakpastian yang masih saya miliki sebagai pertanyaan. Pada dasarnya, saya tidak mengerti bagaimana bagian menulis tes ini. Dengan asumsi saya tidak menerima panduan lebih lanjut dari penyelia saya (kemungkinan), ada di ballpark saya untuk tidak hanya mempelajari apa yang komponen ini lakukan tetapi untuk memutuskan tes apa yang sebenarnya berguna sebagai tes regresi.
Sebagai profesional yang telah bekerja dengan proyek seperti ini lebih lama daripada saya, dapatkah Anda menawarkan panduan tentang cara menulis tes unit dalam situasi seperti ini?
sumber
How do I write unit tests for legacy code that I can't build, run, simulate, read about, or otherwise understand?
- Kamu tidak bisa. Anda harus setidaknya tahu apa output yang diharapkan untuk input yang diberikan.Jawaban:
Untuk perkiraan pertama, para pemangku kepentingan dari suite uji adalah pengembang / pengelola kode. Anda akan membutuhkan waktu mereka. Bersikeras ini.
Tanyakan kepada mereka tentang masalah yang mereka hadapi.
Tanyakan kepada mereka tentang bug yang mereka perbaiki baru-baru ini (dalam beberapa tahun terakhir, dengan asumsi ini adalah proyek yang sangat lambat).
Saya mendapat kesan bahwa Anda tidak mengharapkan mereka ramah terhadap pekerjaan Anda; mungkin kau benar. Tetapi saya tidak berpikir Anda dapat membangun sesuatu yang bermanfaat tanpa bantuan mereka.
Mereka akan memegang tangan Anda melalui penulisan tes pertama. Mungkin Anda akan menyeretnya, tetapi Anda akan berpegangan tangan.
Setelah Anda memiliki satu tes, semoga akan lebih jelas bagaimana menulis yang kedua. Jika Anda berhasil membangun hubungan apa pun, tentu akan lebih jelas.
sumber
Saya akan berasumsi pada titik tertentu Anda bisa mendapatkan kode untuk setidaknya mengkompilasi. Jika Anda bahkan tidak bisa sejauh itu, Anda sedang dalam tugas bodoh.
Kurangnya persyaratan, spesifikasi, atau tangkapan layar yang tepat bukanlah pemblokir untuk tes penulisan. Selama Anda dapat membaca kode sumber, Anda dapat menulis tes.
Jika Anda diberi izin untuk memperbaiki basis kode untuk mengisolasi hal-hal seperti koneksi database di belakang antarmuka mereka sendiri, menjadi mungkin untuk menulis beberapa tes unit kotak hitam - pada dasarnya menulis tes untuk melemparkan beberapa input pada suatu metode dan menegaskan perilaku atau outputnya. Dapatkan tes yang mencakup setiap baris kode dalam satu metode dan kemudian minta salah satu anggota senior tim meninjau tes Anda.
Jika Anda tidak diberi izin untuk memperbaiki basis kode untuk menulis tes unit maka tes integrasi penuh atau tes otomatisasi UI adalah satu-satunya pilihan Anda. Bahkan kemudian, pengujian kotak hitam adalah strategi terbaik Anda - melemparkan beberapa input di UI dan lihat bagaimana reaksinya. Buat pernyataan Anda. Mintalah anggota senior tim meninjau tes Anda.
Pada titik tertentu Anda akan memiliki tes otomatis yang cukup sehingga Anda dapat mulai refactoring basis kode dengan percaya diri untuk memperkenalkan tes unit. Pengujian UI memastikan case penggunaan bisnis utama berfungsi, dan kemudian Anda dapat memperbaiki arsitektur yang kondusif untuk pengujian tingkat unit atau komponen.
Manfaat lain dari tes UI adalah bahwa Anda dapat membangun reputasi dengan tim Anda bahwa Anda memahami basis kode, yang pada gilirannya membuatnya lebih terbuka untuk Anda memperkenalkan perubahan, karena buktinya ada di puding. Dan Anda akan membuat puding dengan cara menulis tes kelulusan.
Pendeknya:
Anda akan terkejut betapa cepatnya Anda dapat mempelajari tampilan gambar besar dari aplikasi 700.000 baris
sumber
Berdasarkan uraian masalah dan komentar Anda, saya pikir yang terbaik yang dapat Anda lakukan adalah mulai dengan Java API dan mencoba membangun satu unit test di sekitar metode yang terisolasi.
Tanpa akses ke kode, saya hanya bisa memberi Anda panduan terbatas tetapi saya akan mencari sesuatu yang di dalamnya a) tidak memiliki dependensi b) tidak membuat perubahan keadaan. Sebagai contoh. katakanlah ada metode yang mengambil nilai dan memeriksa bahwa itu jatuh dalam kisaran yang diberikan. Jika Anda tidak dapat menemukan sesuatu tanpa dependensi, coba sesuatu yang mengambil nilai dari dependensi dan mencoba untuk mengejeknya.
Setelah Anda menemukan sesuatu yang kecil seperti ini, Anda dapat mulai membuat tes. Jika metode ini menguji nilai positif, maka berikan nilai negatif dan pastikan itu menangkapnya, dll. Masalahnya di sini adalah Anda mungkin tidak tahu pasti apa perilaku yang benar. Anda mungkin perlu meminta bantuan atau menggali melalui dokumentasi untuk itu.
Anda tidak mungkin terlalu jauh dengan ini. Kenyataannya adalah bahwa menulis kode sehingga dapat diuji unit adalah seni untuk dirinya sendiri. Kode yang tidak ditulis dengan ini dalam pikiran bisa sulit untuk mustahil untuk unit test.
Opsi lain yang mungkin lebih mudah diimplementasikan adalah pengujian kompatibilitas biner. Artinya, Anda menangkap input dan output dari suatu sistem dan kemudian untuk menguji, Anda memberi makan input yang sama dan membandingkan output. Ini tidak akan memberi tahu Anda apakah kode itu benar atau salah untuk memulainya, tetapi dapat membantu mendeteksi kesalahan regresi di mana segala sesuatu berubah secara tidak sengaja ketika membuat beberapa modifikasi lainnya. Anda harus dapat menjalankan seluruh aplikasi untuk mewujudkannya.
sumber