- Pertanyaan ini bukan tentang Kerangka Pengujian Unit.
- Pertanyaan ini bukan tentang menulis Tes Unit.
- Pertanyaan ini adalah tentang di mana harus menulis kode UT dan bagaimana / kapan / di mana mengkompilasi dan menjalankannya.
Dalam Bekerja Efektif dengan Legacy Code , Michael Feathers menegaskan hal itu
tes unit yang bagus ... berjalan cepat
dan itu
Tes unit yang membutuhkan 1/10 detik untuk dijalankan adalah tes unit lambat.
Saya pikir definisi ini masuk akal. Saya juga berpikir bahwa mereka menyiratkan bahwa Anda harus menyimpan satu set Tes Unit dan satu set Tes Kode Itu yang Dibutuhkan Lebih Lama secara terpisah, tapi saya kira itu harga yang Anda bayar untuk hanya memanggil sesuatu Tes Unit jika berjalan (sangat) cepat .
Jelas masalah di C ++ adalah bahwa untuk "lari" Anda Unit Uji ( s ), Anda harus:
- Edit kode Anda (produksi atau Tes Unit, tergantung pada "siklus" Anda berada di mana)
- Menyusun
- Tautan
- Mulai Unit Uji Executable ( s )
Sunting (setelah pemilihan umum yang aneh) : Sebelum masuk ke detail, saya akan mencoba meringkas titik di sini:
Bagaimana kode C ++ Unit Test dapat diatur secara efektif, sehingga efisien untuk mengedit kode (test) dan menjalankan kode tes?
Masalah pertama adalah memutuskan di mana harus meletakkan kode Uji Unit sehingga:
- itu "alami" untuk mengedit dan melihatnya dalam kombinasi dengan kode produksi terkait.
- mudah / cepat untuk memulai siklus kompilasi untuk unit yang sedang Anda ubah
Masalah kedua , terkait, adalah apa yang harus dikompilasi sehingga umpan baliknya instan.
Opsi ekstrem:
- Setiap Unit-Tes-Tes-Unit hidup dalam file cpp yang terpisah dan file cpp ini dikompilasi + ditautkan secara terpisah (bersama dengan kode sumber file unit yang diuji) ke satu executable yang kemudian menjalankan Tes Unit yang satu ini.
- (+) Ini meminimalkan waktu startup (kompilasi + tautan!) Untuk Unit Uji tunggal.
- (+) Tes berjalan sangat cepat, karena hanya menguji satu unit.
- (-) Mengeksekusi seluruh rangkaian harus memulai banyak proses. Bisa jadi masalah untuk dikelola.
- (-) overhead proses mulai akan terlihat
- Sisi lain akan memiliki - masih - satu file cpp per tes, tetapi semua file cpp tes (bersama dengan kode yang mereka uji!) Dihubungkan ke satu yang dapat dieksekusi (per modul / per proyek / pilih pilihan Anda).
- (+) Waktu kompilasi masih akan OK, karena hanya kode yang diubah yang akan dikompilasi.
- (+) Menjalankan seluruh suite itu mudah, karena hanya ada satu exe yang harus dijalankan.
- (-) Suite akan membutuhkan waktu lama untuk ditautkan, karena setiap kompilasi ulang terhadap objek apa pun akan memicu tautan ulang.
- (-) (?) Gugatan akan memakan waktu lebih lama untuk dijalankan, meskipun jika semua Tes Unit cepat, waktunya harus OK.
Jadi, bagaimana dunia nyata Unit C ++ Tes ditangani? Jika saya hanya menjalankan hal-hal itu setiap malam / jam, bagian kedua tidak terlalu penting, tetapi bagian pertama, yaitu bagaimana "memasangkan" kode UT ke kode produksi, sehingga "wajar" bagi pengembang untuk menjaga keduanya tetap dalam fokus selalu penting menurut saya. (Dan jika pengembang memiliki kode UT dalam fokus, mereka ingin menjalankannya, yang membawa kita kembali ke bagian dua.)
Kisah dan pengalaman dunia nyata dihargai!
Catatan:
- Pertanyaan ini sengaja meninggalkan platform yang tidak ditentukan dan sistem pembuatan / proyek.
- Pertanyaan yang Ditandai UT & C ++ adalah tempat yang bagus untuk memulai, tetapi sayangnya terlalu banyak pertanyaan, dan terutama jawaban, terlalu terfokus pada detail atau kerangka kerja tertentu.
- Beberapa waktu yang lalu, saya menjawab pertanyaan serupa tentang struktur untuk meningkatkan unit test. Saya menemukan struktur ini kurang untuk "nyata", Tes Unit cepat. Dan saya menemukan pertanyaan lain terlalu sempit, maka pertanyaan baru ini.
:-(
Di mana Anda seharusnya mencari jawaban untuk pertanyaan seperti itu jika tidak ada di forum ini?
Pipeline<A,B>.connect(Pipeline<B,C>)
harus dikompilasi sedangkan Pipeline<A,B>.connect(Pipeline<C,D>)
seharusnya tidak mengkompilasi: Jenis output dari tahap pertama tidak sesuai dengan jenis input dari tahap kedua.