Saya memiliki tes unit (nUnit). Banyak lapisan di bawah tumpukan panggilan, sebuah metode akan gagal jika dijalankan melalui pengujian unit.
Idealnya Anda akan menggunakan sesuatu seperti mengejek untuk mengatur objek yang bergantung pada metode ini tetapi ini adalah kode pihak ke-3 dan saya tidak dapat melakukannya tanpa banyak pekerjaan.
Saya tidak ingin mengatur metode khusus nUnit - ada terlalu banyak level di sini dan cara yang buruk dalam melakukan pengujian unit.
Sebaliknya apa yang ingin saya lakukan adalah menambahkan sesuatu seperti ini jauh di dalam tumpukan panggilan
#IF DEBUG // Unit tests only included in debug build
if (IsRunningInUnitTest)
{
// Do some setup to avoid error
}
#endif
Jadi ada ide tentang cara menulis IsRunningInUnitTest?
PS Saya sepenuhnya sadar bahwa ini bukan desain yang bagus, tapi saya pikir ini lebih baik daripada alternatifnya.
sumber
Jawaban:
Saya pernah melakukan ini sebelumnya - saya harus menahan hidung saat melakukannya, tetapi saya berhasil. Pragmatisme mengalahkan dogmatisme setiap saat. Tentu saja, jika ada adalah cara yang baik Anda dapat refactor untuk menghindarinya, yang akan menjadi besar.
Pada dasarnya saya memiliki kelas "UnitTestDetector" yang memeriksa apakah rakitan kerangka NUnit dimuat di AppDomain saat ini. Ini hanya perlu melakukan ini sekali, lalu cache hasilnya. Jelek, tapi sederhana dan efektif.
sumber
AppDomain.GetAssemblies
dan memeriksa rakitan yang relevan - untuk MSTest Anda perlu melihat rakitan mana yang dimuat. Lihat jawaban Ryan sebagai contoh.Mengambil ide Jon, inilah yang saya pikirkan -
Pipa di belakang kita semua anak laki-laki cukup besar untuk mengenali ketika kita melakukan sesuatu yang mungkin tidak seharusnya kita lakukan;)
sumber
Diadaptasi dari jawaban Ryan. Yang ini untuk kerangka pengujian unit MS.
Alasan saya membutuhkan ini adalah karena saya menampilkan MessageBox pada kesalahan. Tetapi pengujian unit saya juga menguji kode penanganan kesalahan, dan saya tidak ingin MessageBox muncul saat menjalankan pengujian unit.
Dan inilah unit test untuk itu:
sumber
Menyederhanakan solusi Ryan, Anda cukup menambahkan properti statis berikut ke kelas mana pun:
sumber
Saya menggunakan pendekatan yang mirip dengan tallseth
Ini adalah kode dasar yang dapat dengan mudah dimodifikasi untuk menyertakan caching. Ide bagus lainnya adalah menambahkan setter ke
IsRunningInUnitTest
dan memanggilUnitTestDetector.IsRunningInUnitTest = false
titik masuk utama proyek Anda untuk menghindari eksekusi kode.sumber
Mungkin berguna, memeriksa ProcessName saat ini:
Dan fungsi ini juga harus diperiksa oleh unittest:
Referensi:
Matthew Watson di http://social.msdn.microsoft.com/Forums/en-US/csharplanguage/thread/11e68468-c95e-4c43-b02b-7045a52b407e/
sumber
|| processName.StartsWith("testhost") // testhost.x86
untuk VS 2019Dalam mode uji,
Assembly.GetEntryAssembly()
tampaknyanull
.Perhatikan bahwa jika
Assembly.GetEntryAssembly()
adalahnull
,Assembly.GetExecutingAssembly()
tidak.The Dokumentasi mengatakan:
GetEntryAssembly
Metode dapat kembalinull
ketika berhasil perakitan telah dimuat dari aplikasi unmanaged.sumber
Di suatu tempat dalam proyek yang sedang diuji:
Di suatu tempat dalam proyek pengujian unit Anda:
Elegan, tidak. Tapi terus terang dan cepat.
AssemblyInitializer
adalah untuk MS Test. Saya berharap kerangka pengujian lain memiliki padanan.sumber
IsRunningInUnitTest
tidak disetel ke true di AppDomain tersebut.Saya menggunakan ini hanya untuk melewatkan logika yang menonaktifkan semua TraceAppenders di log4net selama startup ketika tidak ada debugger yang terpasang. Hal ini memungkinkan pengujian unit untuk masuk ke jendela hasil Resharper bahkan saat berjalan dalam mode non-debug.
Metode yang menggunakan fungsi ini dipanggil saat aplikasi dimulai atau saat memulai perlengkapan uji.
Ini mirip dengan posting Ryan tetapi menggunakan LINQ, menjatuhkan persyaratan System.Reflection, tidak menyimpan hasilnya, dan bersifat pribadi untuk mencegah penyalahgunaan (tidak disengaja).
sumber
Memiliki referensi ke kerangka nunit tidak berarti bahwa pengujian benar-benar berjalan. Misalnya dalam Unity ketika Anda mengaktifkan tes mode putar, referensi biarawati ditambahkan ke proyek. Dan ketika Anda menjalankan permainan, referensi tersebut ada, sehingga UnitTestDetector tidak akan bekerja dengan benar.
Alih-alih memeriksa perakitan nunit, kita dapat meminta nunit api untuk memeriksa apakah kode sedang menjalankan pengujian sekarang atau tidak.
Edit:
Berhati-hatilah karena TestContext dapat dibuat secara otomatis jika diperlukan.
sumber
Gunakan saja ini:
Dalam mode uji, ini akan mengembalikan nilai salah.
sumber
Saya tidak senang mengalami masalah ini baru-baru ini. Saya menyelesaikannya dengan cara yang sedikit berbeda. Pertama, saya tidak ingin membuat asumsi bahwa framework nunit tidak akan pernah dimuat di luar lingkungan pengujian; Saya sangat khawatir tentang pengembang yang menjalankan aplikasi di mesin mereka. Jadi saya menjalankan tumpukan panggilan sebagai gantinya. Kedua, saya dapat membuat asumsi bahwa kode pengujian tidak akan pernah dijalankan terhadap rilis biner, jadi saya memastikan kode ini tidak ada dalam sistem rilis.
sumber
bekerja seperti pesona
.
sumber
Tes unit akan melewati titik masuk aplikasi. Setidaknya untuk wpf, winforms dan aplikasi konsol
main()
tidak dipanggil.Jika metode utama dipanggil daripada saat run-time , jika tidak, kita berada dalam mode pengujian unit :
sumber
Mempertimbangkan kode Anda berjalan secara normal di utas utama (gui) dari aplikasi formulir windows dan Anda ingin kode tersebut berperilaku berbeda saat menjalankan pengujian, Anda dapat memeriksa
Saya menggunakan ini untuk kode yang saya inginkan
fire and forgot
dalam aplikasi gui tetapi dalam pengujian unit saya mungkin memerlukan hasil yang dihitung untuk sebuah pernyataan dan saya tidak ingin mengacaukan beberapa utas yang sedang berjalan.Bekerja untuk MSTest. Keuntungannya adalah kode saya tidak perlu memeriksa kerangka pengujian itu sendiri dan jika saya benar-benar membutuhkan perilaku async dalam pengujian tertentu, saya dapat mengatur SynchronizationContext saya sendiri.
Sadarilah bahwa ini bukan metode yang dapat diandalkan
Determine if code is running as part of a unit test
seperti yang diminta oleh OP karena kode dapat berjalan di dalam utas tetapi untuk skenario tertentu ini bisa menjadi solusi yang baik (juga: Jika saya sudah menjalankan dari utas latar belakang, itu mungkin tidak diperlukan untuk memulai yang baru).sumber
Application.Current adalah null saat berjalan di bawah unit tester. Setidaknya untuk aplikasi WPF saya menggunakan penguji Unit MS. Itu adalah tes yang mudah dilakukan jika diperlukan. Juga, sesuatu yang perlu diingat saat menggunakan Application.Current dalam kode Anda.
sumber
Saya telah menggunakan berikut ini di VB dalam kode saya untuk memeriksa apakah kita berada dalam pengujian unit. secara khusus saya tidak ingin tes membuka Word
sumber
Bagaimana kalau menggunakan refleksi dan sesuatu seperti ini:
var underTest = Assembly.GetCallingAssembly ()! = typeof (MainForm) .Assembly;
Rakitan panggilan akan menjadi tempat kasus pengujian Anda dan hanya menggantikan MainForm beberapa jenis yang ada di kode Anda yang sedang diuji.
sumber
Ada solusi yang sangat sederhana juga saat Anda menguji kelas ...
Cukup berikan kelas tempat Anda menguji properti seperti ini:
Sekarang pengujian unit Anda dapat menyetel boolean "thisIsUnitTest" ke true, jadi dalam kode yang ingin Anda lewati, tambahkan:
Lebih mudah dan lebih cepat daripada memeriksa majelis. Mengingatkan saya pada Ruby On Rails di mana Anda akan melihat apakah Anda berada di lingkungan TEST.
sumber