Menurut pendapat saya, unit test harus ditempatkan dalam rakitan terpisah dari kode produksi. Berikut adalah beberapa kontra menempatkan tes unit dalam rakitan atau rakitan yang sama dengan kode produksi adalah:
- Tes unit dikirimkan dengan kode produksi. Satu-satunya yang dikirimkan dengan kode produk adalah kode produksi.
- Sidang tidak perlu membengkak oleh unit test.
- Tes unit dapat memengaruhi proses pembuatan seperti pembuatan otomatis atau berkelanjutan.
Saya tidak benar-benar tahu pro. Memiliki proyek tambahan (atau 10) bukanlah sebuah tipuan.
Sunting: Info Lebih Lanjut Tentang Pembuatan dan Pengiriman
Saya selanjutnya akan merekomendasikan bahwa setiap proses pembuatan otomatis menempatkan produksi dan pengujian unit ke lokasi yang berbeda. Idealnya, proses pembuatan unit test hanya berjalan jika kode produksi dibangun, dan menyalin file produk ke direktori unit test. Melakukannya dengan cara ini menghasilkan bit aktual yang dipisahkan untuk pengiriman, dll. Selain itu, cukup sepele untuk menjalankan pengujian unit otomatis pada titik ini pada semua pengujian dalam direktori tertentu.
Untuk meringkas, berikut adalah ide umum untuk pembuatan dan pengujian harian dan pengiriman bit dan file lainnya:
- Produksi build berjalan, menempatkan file produksi ke direktori "produksi" tertentu.
- Bangun proyek produksi saja.
- Salin bit yang dikompilasi dan file lainnya ke direktori "produksi".
- Salin bit dan file lain ke direktori kandidat rilis, alias direktori rilis Natal adalah "Release20081225".
- Jika build produksi berhasil, unit test build berjalan.
- Salin kode produksi ke direktori "tes".
- Buat unit test ke direktori "tes".
- Jalankan tes unit.
- Kirim pemberitahuan pembuatan dan hasil pengujian unit ke pengembang.
- Ketika seorang kandidat rilis (seperti Release20081225) diterima, kirimkan bit-bit ini.
#if
. Simbol khusus ini dapat diubah menggunakan parameter baris perintah kompiler di skrip perangkat lunak CI Anda. Lihat msdn.microsoft.com/en-us/library/4y6tbswk.aspx .Proyek terpisah, tetapi dalam solusi yang sama. (Saya telah mengerjakan produk dengan solusi terpisah untuk pengujian dan kode produksi - ini mengerikan. Anda selalu beralih di antara keduanya.)
Alasan untuk proyek terpisah adalah seperti yang dinyatakan oleh orang lain. Perhatikan bahwa jika Anda menggunakan tes yang digerakkan oleh data, Anda mungkin berakhir dengan mengasapi yang cukup signifikan jika Anda memasukkan tes dalam rakitan produksi.
Jika Anda memerlukan akses ke anggota internal kode produksi, gunakan InternalsVisibleTo .
sumber
[assembly:InternalsVisibleTo("UnitTestProjectName")]
keAssemblyInfo.cs
file proyek Anda .Saya tidak mengerti keberatan yang sering diajukan tes dengan kode produksi. Saya memimpin sebuah tim di sebuah microcap kecil (tumbuh dari 14 menjadi 130 orang). Kami memiliki sekitar setengah lusin aplikasi Java dan kami merasa sangat berharga untuk menerapkan tes ke lapangan untuk menjalankannya pada spesifikmesin yang menunjukkan perilaku tidak biasa. Masalah acak terjadi di lapangan dan mampu melempar beberapa ribu unit tes pada misteri dengan biaya nol sangat berharga dan sering didiagnosis masalah dalam hitungan menit ... termasuk masalah pemasangan, masalah RAM flaky, masalah khusus mesin, masalah jaringan terkelupas, dll, dll. Saya pikir ini sangat berharga untuk melakukan tes di lapangan. Juga, masalah acak muncul pada waktu yang acak dan itu bagus untuk memiliki unit test duduk di sana sudah menunggu untuk dieksekusi pada saat pemberitahuan. Ruang hard drive murah. Sama seperti kita mencoba untuk menjaga data dan fungsi bersama (desain OO), saya pikir ada sesuatu yang secara fundamental berharga dalam menjaga kode dan pengujian bersama (fungsi + tes yang memvalidasi fungsi).
Saya ingin meletakkan tes saya di proyek yang sama di C # /. NET / Visual Studio 2008, tapi saya masih belum menyelidiki ini cukup untuk mencapainya.
Salah satu manfaat besar menjaga Foo.cs dalam proyek yang sama dengan FooTest.cs adalah bahwa pengembang terus-menerus diingatkan ketika sebuah kelas kehilangan tes saudara kandung! Ini mendorong praktik pengkodean uji-didorong yang lebih baik ... lubang lebih jelas.
sumber
Masukkan tes Unit dalam proyek yang sama dengan kode untuk mencapai enkapsulasi yang lebih baik.
Anda dapat dengan mudah menguji metode internal, yang berarti Anda tidak akan membuat metode publik yang seharusnya internal.
Juga sangat menyenangkan untuk memiliki unit test yang dekat dengan kode yang Anda tulis. Saat Anda menulis metode, Anda dapat dengan mudah menemukan unit test yang sesuai karena itu dalam proyek yang sama. Saat Anda membangun unit yang menyertakan unitTests, kesalahan apa pun di unitTest akan memberi Anda kompilator, jadi Anda harus tetap up-to-date, yang belum diperbarui, hanya untuk membangun. Memiliki unittest dalam proyek terpisah, mungkin menyebabkan beberapa pengembang lupa membangun proyek unittest, dan melewatkan tes yang rusak untuk sementara waktu.
Dan Anda dapat menghapus tes unit dari kode produksi, dengan menggunakan tag kompilasi (IF #Debug).
Tes Integrasi Otomatis (dibuat i NUnit) harus dalam proyek terpisah karena mereka bukan milik proyek tunggal.
sumber
Release
build dan beberapa "heisenbugs" dapat gagal.InternalsVisibleTo
memungkinkan Anda untuk menguji metode internal dari proyek pengujian terpisahDebug
,Approval
danRelease
; dan kompilasi persetujuan dengan semua optimisasi rilis. Juga, biasanya unit test tidak pandai mendeteksi heisenbugs di tempat pertama (menurut pengalaman saya). Anda cenderung memerlukan tes regresi integrasi khusus untuk hal tersebut - dan Anda dapat menempatkannya berdampingan.Setelah menghabiskan beberapa waktu di proyek-proyek TypeScript, di mana tes sering ditempatkan dalam file di samping kode yang mereka uji, saya tumbuh lebih suka pendekatan ini daripada menjaga mereka terpisah:
Jadi ketika saya memulai proyek .NET Core baru-baru ini saya ingin melihat apakah mungkin untuk meniru struktur ini dalam proyek C # tanpa mengirimkan tes atau rakitan uji dengan rilis akhir.
Menempatkan baris berikut dalam file proyek tampaknya bekerja dengan baik sejauh ini:
Di atas memastikan bahwa dalam
Release
konfigurasi semua file yang disebutkan*.Tests.cs
dikecualikan dari kompilasi, dan juga bahwa referensi paket pengujian unit yang diperlukan dihapus.Jika Anda masih ingin dapat menguji unit kelas dalam konfigurasi rilis mereka, Anda bisa membuat konfigurasi baru yang berasal dari yang
Release
disebut sesuatu sepertiReleaseContainingTests
.Pembaruan: Setelah menggunakan teknik ini untuk sementara waktu, saya juga menemukan bahwa sangat membantu untuk menyesuaikan ikon Anda di VS Code untuk membuat pengujian (dan hal-hal lain) sedikit lebih menonjol di panel penjelajah:
Untuk melakukan ini, gunakan ekstensi Tema Bahan Ikon dan tambahkan sesuatu seperti berikut ke preferensi Kode VS Anda JSON:
sumber
Tes unit saya selalu berjalan dalam proyek terpisah. Bahkan, untuk setiap proyek yang saya miliki dalam solusi saya, ada proyek uji terpisah yang menyertainya. Kode pengujian bukan kode aplikasi dan tidak boleh berbaur dengannya. Satu keuntungan untuk menjaga mereka dalam proyek terpisah - setidaknya menggunakan TestDriven.Net - adalah bahwa saya dapat mengklik kanan pada proyek uji dan menjalankan semua tes dalam proyek itu, menguji seluruh perpustakaan kode aplikasi dengan satu klik.
sumber
Jika kerangka kerja NUnit digunakan, ada alasan tambahan untuk menempatkan tes dalam proyek yang sama. Pertimbangkan contoh kode produksi berikut yang dicampur dengan unit test:
Tes unit di sini berfungsi sebagai dokumentasi dan spesifikasi untuk kode yang diuji. Saya tidak tahu bagaimana mencapai efek mendokumentasikan diri ini, dengan tes yang terletak di proyek terpisah. Pengguna fungsi harus mencari tes untuk melihat kasus-kasus uji, yang tidak mungkin.
Pembaruan : Saya tahu bahwa penggunaan
TestCase
atribut seperti itu tidak dimaksudkan oleh pengembang NUnit, tetapi mengapa tidak?sumber
Saya berfluktuasi antara proyek yang sama dan proyek yang berbeda.
Jika Anda melepaskan pustaka yang melepaskan kode tes dengan kode produksi adalah masalah, jika tidak, menurut saya biasanya tidak (walaupun ada hambatan psikologis yang kuat sebelum Anda mencoba).
Ketika menempatkan tes dalam proyek yang sama saya merasa lebih mudah untuk beralih antara tes dan kode yang mereka uji, dan lebih mudah untuk refactor / memindahkannya.
sumber
Saya menempatkan mereka dalam proyek terpisah. Nama majelis mencerminkan nama namespace, sebagai aturan umum bagi kami. Jadi jika ada proyek bernama Company.Product.Feature.sln, ia memiliki output (nama perakitan) dari Company.Product.Feature.dll. Proyek pengujian adalah Company.Product.Feature.Tests.sln, menghasilkan Company.Product.Feature.Tests.dll.
Anda sebaiknya menyimpannya dalam satu solusi dan mengendalikan output melalui Configuration Manager. Kami memiliki konfigurasi bernama untuk masing-masing cabang utama (Pengembangan, Integrasi, Produksi) sebagai pengganti menggunakan Debug dan Rilis default. Setelah Anda menyiapkan konfigurasi, Anda dapat memasukkan atau mengecualikannya dengan mengeklik kotak centang "Bangun" di Pengelola Konfigurasi. (Untuk mendapatkan Manajer Konfigurasi, klik kanan solusi dan pergi ke Manajer Konfigurasi.) Catatan, bahwa saya menemukan CM di Visual Studio menjadi buggy di kali. Beberapa kali, saya harus masuk ke proyek dan / atau file solusi untuk membersihkan target yang dibuatnya.
Selain itu, jika Anda menggunakan Pembangun Tim (dan saya yakin bahwa perkakas .NET build lainnya sama), maka Anda dapat mengaitkan pembuatan dengan konfigurasi yang dinamai. Ini berarti bahwa jika Anda tidak membangun pengujian unit untuk bangunan "Produksi", misalnya, proyek pembangunan juga dapat mengetahui pengaturan ini dan tidak membangunnya karena ditandai sebagai demikian.
Kami juga biasa melakukan XCopy dari mesin build. Script hanya akan menghilangkan menyalin apa pun yang bernama * .Tests.Dll dari yang digunakan. Itu sederhana, tetapi berhasil.
sumber
Saya akan mengatakan memisahkan mereka.
Di atas alasan lain yang disebutkan, memiliki kode dan tes bersama-sama mengabaikan angka cakupan tes. Ketika Anda melaporkan tentang cakupan unit test - cakupan yang dilaporkan lebih tinggi karena tes tercakup ketika Anda menjalankan tes unit. Ketika Anda melaporkan tentang cakupan tes integrasi, cakupan yang dilaporkan lebih rendah karena tes integrasi tidak akan menjalankan tes unit.
sumber
Saya benar-benar terinspirasi oleh kerangka pengujian unit perpustakaan Flood NN oleh Robert Lopez. Ini menggunakan proyek yang berbeda untuk setiap kelas unit yang diuji, dan memiliki satu solusi untuk menampung semua proyek ini, serta proyek utama yang mengkompilasi dan menjalankan semua tes.
Yang rapi juga tata letak proyek. File sumber ada dalam folder, tetapi kemudian folder untuk proyek VS ada di bawah ini. Ini memungkinkan Anda membuat subfolder yang berbeda untuk kompiler yang berbeda. Semua proyek VS dikirimkan dengan kode, sehingga sangat mudah bagi siapa saja untuk menjalankan salah satu atau semua tes unit.
sumber
Saya tahu ini adalah pertanyaan yang sangat lama, tetapi saya ingin menambahkan pengalaman saya di sana. Saya baru-baru ini mengubah kebiasaan pengujian unit dari proyek yang terpisah ke yang sama.
Mengapa?
Pertama saya sangat cenderung menjaga struktur folder proyek utama sama dengan proyek uji. Jadi, jika saya memiliki file di bawah
Providers > DataProvider > SqlDataProvider.cs
maka saya membuat struktur yang sama di proyek pengujian unit saya sepertiProviders > DataProvider > SqlDataProvider.Tests.cs
Tetapi setelah proyek semakin besar dan lebih besar, setelah Anda memindahkan file dari satu folder ke folder lain, atau dari satu proyek ke yang lain, maka pekerjaan yang sangat rumit untuk menyinkronkannya dengan proyek-proyek unit test.
Kedua, tidak selalu sangat mudah dinavigasi dari kelas untuk diuji ke kelas uji unit. Ini bahkan lebih sulit untuk JavaScript dan Python.
Baru-baru ini, saya mulai berlatih bahwa, setiap file yang saya buat (misalnya
SqlDataProvider.cs
) saya membuat file lain dengan akhiran Test, sepertiSqlDataProvider.Tests.cs
Pada awalnya tampaknya akan membengkak file dan referensi perpustakaan, tetapi dalam jangka panjang, Anda akan menghilangkan sindrom file bergerak pada pandangan pertama, dan Anda juga akan memastikan, setiap file yang sedang diuji akan memiliki file pasangan. dengan
.Tests
akhiran. Ini memberi Anda mudah melompat ke file uji (karena berdampingan) daripada melihat melalui proyek terpisah.Anda bahkan dapat menulis aturan bisnis untuk memindai melalui proyek dan mengidentifikasi kelas yang tidak memiliki file .Tests, dan melaporkannya kepada pemilik. Anda juga dapat memberi tahu pelari ujian Anda dengan mudah ke
.Tests
kelas sasaran .Khusus untuk Js dan Python Anda tidak perlu mengimpor referensi Anda dari jalur yang berbeda, Anda cukup menggunakan jalur file target yang sama sedang diuji.
Saya menggunakan praktik ini untuk sementara waktu, dan saya pikir itu adalah pertukaran yang sangat masuk akal antara ukuran proyek vs pemeliharaan dan kurva pembelajaran untuk pendatang baru ke proyek.
sumber
Seperti orang lain telah menjawab - letakkan tes dalam proyek yang terpisah
Satu hal yang belum disebutkan adalah kenyataan bahwa Anda tidak dapat benar-benar lari
nunit3-console.exe
melawan apa pun selain.dll
file.Jika Anda berencana menjalankan tes Anda melalui TeamCity, ini akan menimbulkan masalah.
Katakanlah Anda memiliki proyek aplikasi konsol. Ketika Anda mengkompilasi, itu mengembalikan file yang
.exe
dapat dieksekusi kebin
folder.Dari
nunit3-console.exe
Anda tidak akan dapat menjalankan tes yang ditentukan dalam aplikasi konsol itu.Dengan kata lain, aplikasi konsol mengembalikan
exe
file dan perpustakaan kelas mengembalikandll
file.Saya baru saja mendapat hal ini hari ini dan itu menyebalkan :(
sumber
Saya baru-baru ini ditempatkan di buruh pelabuhan. Saya tidak melihat nilai memiliki proyek terpisah ketika Dockerfile dapat dengan mudah menyalin direktori / src dan meninggalkan direktori / test. Tapi saya baru mengenal dotnet dan mungkin kehilangan sesuatu.
sumber
Proyek terpisah, meskipun saya berdebat dengan diri saya sendiri apakah mereka harus berbagi svn yang sama. Saat ini, saya memberi mereka repositori svn terpisah, yang disebut
"MyProject" - untuk proyek itu sendiri
dan satu disebut
"MyProjectTests" - untuk tes yang terkait dengan MyProject.
Ini cukup bersih dan memiliki keunggulan yang berkaitan dengan proyek dan berkomitmen untuk tes yang cukup terpisah. Ini juga berarti Anda dapat menyerahkan svn proyek jika diperlukan, tanpa harus melepaskan tes Anda. Ini juga berarti Anda dapat memiliki direktori cabang / trunk / tag untuk pengujian Anda dan untuk proyek Anda.
Tapi saya semakin cenderung memiliki sesuatu seperti yang berikut ini, dalam satu repositori svn, untuk setiap proyek.
Saya tertarik untuk mengetahui pendapat orang lain tentang solusi ini.
sumber