Masalah dengan atribut DeploymentItem

94

Saat ini saya mempertahankan sistem "lama" yang ditulis dalam C # .net, menghapus beberapa fitur usang dan melakukan beberapa pemfaktoran ulang. Terima kasih Tuhan, orang sebelumnya menulis beberapa tes unit (MSTests). Saya cukup nyaman dengan tes JUnit, tetapi belum melakukan banyak hal dengan MSTests.

Metode pengujian memiliki DeploymentItematribut, menentukan file teks yang diurai oleh metode logika bisnis yang sedang diuji dan yang kedua di DeploymentItemmana hanya jalur yang telah ditentukan berisi sekumpulan file TIF yang harus disebarkan juga.

[TestMethod()]
[DeploymentItem(@"files\valid\valid_entries.txt")]
[DeploymentItem(@"files\tif\")]
public void ExistsTifTest()
{
   ...
}

Tes bekerja sebelumnya, tetapi sekarang saya harus mengubah nama file TIF yang ada di direktori \ files \ tif. Menurut aturan, nama file TIF harus sesuai dengan pola tertentu yang juga diperiksa olehExistsTifTest() metode tersebut. Sekarang saya harus mengubah nama file untuk menyesuaikannya dengan persyaratan baru dan tiba-tiba file TIF tidak lagi digunakan seperti sebelumnya.

Dapatkah seseorang memberi saya petunjuk mengapa ini terjadi atau apa yang mungkin menjadi penyebabnya? Hal yang sama terjadi juga jika saya menambahkan file teks baru mengatakan "my2ndTest.txt" di samping "valid_entries.txt" di direktori \ files \ valid \ dengan atribut DeploymentItem yang sesuai pada metode pengujian. File tidak diterapkan?

Sekarang saya mendapatkan gambar yang diterapkan dengan menentukan jalur penerapan langsung di testrunconfig, tetapi saya ingin memahami mengapa hal-hal ini terjadi atau mengapa misalnya file baru saya "my2ndTest.txt" tidak diterapkan sementara yang lain melakukannya.

Juri
sumber
2
Kunci utama di sini adalah menyadari bahwa semua item yang ditentukan dalam DeploymentItemAttribute akan disalin ke lokasi tempat rakitan pengujian Anda dijalankan. Dengan kata lain, jika Anda berharap itu akan mempertahankan struktur direktori Anda, Anda akan kurang beruntung. Jika Anda perlu menyalinnya ke direktori tertentu, gunakan dua parameter versi DeploymentItem (source, outputDir). FYI - Anda dapat menggunakan cara lama untuk mengetahui di mana file dijalankan untuk MsTest dengan memasukkan System.Console.WriteLine (System.Environment.CurrentDirectory) ke salah satu pengujian Anda. NCrunch tidak mengalami masalah ini!
CodeMonkeyKing

Jawaban:

112

DeploymentItem agak berantakan.

Setiap file dalam solusi Anda akan memiliki pengaturan "Salin Ke Folder Output" di VS.NET. Anda memerlukan ini untuk menjadi "Salin Selalu" (atau serupa) untuk memasukkan file ke folder keluaran.

Periksa apakah Anda sudah mendapatkan set ini untuk file baru. Jika Anda tidak memiliki set ini maka file tidak akan disalin ke folder output, dan kemudian mereka tidak dapat digunakan dari folder output ke folder tempat MSTest melakukannya.

Secara pribadi, jika saya memiliki file yang saya perlukan untuk pengujian unit saya, saya telah menemukan bahwa menyematkan file-file itu sebagai sumber daya ke dalam suatu rakitan, dan membuat rakitan itu "membongkar" sendiri selama pengujian adalah cara yang lebih dapat diprediksi dalam melakukan sesuatu. YMMV.

catatan: Komentar ini berdasarkan pengalaman saya dengan VS2010. Komentar atas jawaban saya menunjukkan bahwa ini bukan masalah dengan VS2012. Saya masih mendukung komentar bahwa menggunakan sumber daya tertanam melibatkan lebih sedikit "keajaiban" dan, bagi saya, membuat tahap "mengatur" pengujian unit saya jauh lebih eksplisit.

Martin Peck
sumber
3
Copy To Output Directory tidak pernah memengaruhi cara MSTest menyebarkan file. Jawaban ini salah.
kzu
19
Di VS2010 Premium, membuat perubahan ini (dan tidak ada perubahan lain) menyebabkan file diterapkan. Jadi, saya menyimpulkan berdasarkan bukti nyata bahwa itu TIDAK memengaruhi penerapan MsTest.
JonStonecash
1
Sepakat. Saya telah melihat perubahan tunggal ini mengubah DeploymentItem mengerutkan kening.
Martin Peck
2
Ini tampaknya tidak lagi diperlukan di VS2012. Item penerapan saya sedang diterapkan dengan "Salin ke Folder Output" disetel ke "Jangan Salin".
Mike
31
Sangat bagus bagaimana DeploymentItem memberi Anda pemberitahuan ketika tidak dapat menyalin satu file yang Anda berikan.
74

Di VS2010, Local.testsettings saya memiliki "Enable Deployment" tidak dicentang dan atribut DeploymentItem tidak berfungsi. Saya memeriksanya dan semuanya bekerja dengan baik. Saya harap ini membantu!

Ivan Muzzolini
sumber
2
Aku sudah lama membenturkan kepalaku ke dinding bata berusaha membuatnya bekerja .... terima kasih!
mat-mcloughlin
12
Saya pikir akan lebih baik jika framework mengeluarkan peringatan bahwa atribut DeploymentItem diabaikan jika pengaturan ini dimatikan. Saya juga memberi kesan cekung yang bagus di meja saya.
Alan McBee - MSFT
2
Perhatikan bahwa Local.testsettings ada di Item Solusi
Matthew Lock
Saya juga harus menambahkan direktori yang berisi item yang ingin saya terapkan ke Local.testsettings juga: i.imgur.com/p1z3m9R.png
Matthew Lock
Menggunakan VS2017 pada tahun 2018 memeriksa 'Enable Deployment' masih merupakan solusi untuk masalah ini. Dan sayangnya sekarang masih ada peringatan dari Visual Studio. Jadi terima kasih untuk solusi ini.
Don H
19

Saya juga menghadapi masalah serupa tetapi saya menemukan solusi 3 langkah mudah untuk ini:

Dengan asumsi struktur folder Anda terlihat seperti ini: SolutionFolder\ TestProjectFolder\ SubFolder\

  1. Buka "Item Solusi / Local.testsettings"> "Deployment"> Centang "Enable Deployment"
  2. Jika Anda menggunakan VS2010, pastikan semua file yang ingin Anda terapkan memiliki properti "Salin Ke Folder Output" disetel ke "Salin Selalu" atau "Salin jika Lebih Baru"
  3. Atributkan TestMethod Anda dengan salah satu dari:
    • [DeploymentItem(@"TestProjectFolder\SubFolder")] untuk menyebarkan semua konten <SubFolder> ke direktori Test Run
    • [DeploymentItem(@"TestProjectFolder\SubFolder", "TargetFolder")] untuk menerapkan semua konten <SubFolder>ke <TargetFolder>dalam direktori Test Run

Satu catatan terakhir tentang MSTest (setidaknya untuk VS2010):

Jika Anda ingin <TargetFolder>memiliki nama yang sama dengan <SubFolder>, penggunaan [DeploymentItem(@"SubFolder", @"SubFolder")]akan gagal secara diam-diam karena pelari MSTest mengenai kasus tepi yang konyol. Inilah mengapa Anda harus mengawali <SubFolder>dengan <TestProjectFolder>sebagai:[DeploymentItem(@"TestProjectFolder\SubFolder", @"SubFolder")]

Murari Kumar
sumber
Catatan tentang kegagalan penamaan SubFolder adalah permata.
RJ Lohan
1
VS 2015 tampaknya sedikit berbeda. Saya perlu menghapus bagian "TestPojectFolder" di DeploymentItem Attribute.
uli78
15

Untuk semoga membantu orang lain: Saya mencoba semua saran di sini dan tetap saja item penerapan saya tidak disalin.

Yang harus saya lakukan ( seperti yang disarankan di sini ) adalah menambahkan parameter kedua ke atribut DeploymentItem:

[DeploymentItem(@"UnitTestData\TestData.xml", "UnitTestData")]
Peter K.
sumber
10

Jika Anda masuk ke file .testrunconfig dan di bawah penerapan, hapus centang "Aktifkan Penerapan", pengujian akan berjalan di lokasi normalnya, dan semuanya akan bekerja seperti saat menjalankan aplikasi di luar pengujian unit.

Josh Tutup
sumber
Memiliki beberapa masalah dengan ini juga. Sebagai PM saya tidak memiliki akses ke semua alat yang digunakan oleh dev. Dalam hal ini ReSharper menyalin file dengan benar sementara MSTest gagal melakukannya. -> Saya mengalami kesalahan sementara dev baik-baik saja. Ubah ke 'Test-> Edit Test Settings -> Local settings -> Deployment' termasuk file yang dimaksud, perbaiki ini untuk penggunaan MSTest saya.
sonstabo
9

Ini mungkin tidak berhubungan dengan masalah Anda sebenarnya, tapi berikut beberapa tip yang saya temukan dengan atribut [DeploymentItem].

  1. Salin ke direktori keluaran harus disetel ke Salin Selalu.

Ini TIDAK berfungsi saat digunakan dengan atribut [TestInitialize]

[TestInitialize]
[DeploymentItem("test.xlsx")]
public void Setup()
{

Ini harus ada di [TestMethod] Anda, misalnya

    [TestInitialize]
    public void Setup()
    {
        string spreadsheet = Path.GetFullPath("test.xlsx");
        Assert.IsTrue(File.Exists(spreadsheet));
        ...
    }

    [TestMethod]
    [DeploymentItem("test.xlsx")]
    public void ExcelQuestionParser_Reads_XmlElements()
    {
        ...
    }
Matt Frear
sumber
1
Ini adalah batasan yang sangat mengganggu. Saya merasa untuk banyak kasus, waktu untuk menerapkan harus dalam Inisialisasi. Bagaimana jika semua pengujian saya menggunakan artefak pendukung yang sama? Saya kira saya harus menyalin dan menempelkan dekorator di lusinan metode pengujian? Konyol.
Ryanman
5

Setelah mencoba semua saran lain yang tercantum di sini, saya masih tidak tahu apa yang sedang terjadi. Akhirnya saya menemukan bahwa tidak ada file pengaturan yang dipilih di bawah menu Test / Test Settings, yang berarti bahwa Deployment tidak diaktifkan. Saya mengklik item menu Test / Test Settings / Select Test Settings File, memilih file Local.TestSettings, lalu semuanya bekerja.

Mike
sumber
4

Tidak yakin apakah ini benar-benar menjawab pertanyaan, tetapi mungkin membantu beberapa. Pertama, saya menemukan kotak "Aktifkan Penerapan" harus dicentang agar penerapan berfungsi. Kedua, dokter mengatakan bahwa jalur sumber adalah "relatif terhadap jalur proyek" yang pada awalnya saya maksud dengan folder proyek. Sebenarnya, ini sepertinya merujuk ke folder keluaran build. Jadi jika saya memiliki folder proyek bernama 'TestFiles' dan file di dalamnya bernama Testdata.xml, menggunakan atribut dengan cara ini tidak berfungsi:

[DeploymentItem(@"TestFiles\Testdata.xml")] 

Saya dapat menandai Testdata.xmlfile tersebut Copy Always, sehingga build meletakkan salinan di bawah folder output (misalnya, Debug\TestFiles\TestData.xml). Mekanisme penerapan kemudian akan menemukan salinan file yang terletak di jalur tersebut ( TestFiles\Testdata.xml) relatif terhadap keluaran build. Atau, saya dapat menyetel atribut dengan cara ini:

[DeploymentItem(@"..\\..\TestFiles\Testdata.xml")] 

dan mekanisme penerapan akan menemukan file asli. Jadi baik berfungsi, tetapi saya perhatikan bahwa menggunakan Copy Alwayssaya kadang-kadang mengalami masalah yang sama dengan yang saya alami saat mengedit file app.config dalam sebuah proyek - jika saya tidak mengubah kode atau memaksa membangun kembali, tidak ada yang memicu penyalinan file yang ditandai ke disalin di build.

pengguna1546704
sumber
Jalur relatif adalah masalah bagi saya dan ini memperbaikinya. Saya menambahkan 2 set pernyataan DeploymentItem tergantung pada bagaimana pengujian dijalankan.
Ed Bayiates
3

Saya telah menonaktifkan bendera Penerapan terlebih dahulu. Tetapi bahkan setelah saya mengaktifkannya, untuk beberapa alasan yang tidak diketahui bahkan tidak ada DLL target yang akan tetap disalin. Secara tidak sengaja saya membuka jendela Test Run dan mematikan semua proses sebelumnya dan secara ajaib saya menemukan semua DLL dan file yang saya butuhkan di folder pengujian pada proses berikutnya ... Sangat membingungkan.

Schultz9999
sumber
2

Saya mengalami masalah besar saat mencoba mendapatkan file untuk diterapkan - mencoba semua saran di atas.

Kemudian saya menutup VS2010; memulai ulang, memuat solusi dan semuanya bekerja. (!)

Saya melakukan beberapa pemeriksaan; Setelah menyetel tanda 'Enable deployment' di local.TestSetting, Anda tidak boleh hanya menjalankan ulang pengujian dari jendela Test Results. Anda harus menghapus pengujian sebelumnya dari UI, misalnya dengan menjalankan pengujian yang berbeda, atau dengan membuka kembali solusi Anda.

Stephen Westlake
sumber
2

Jangan gunakan DeploymentItem .

Sangat sulit untuk mengatur dengan benar dan itu tidak bekerja dengan runner pengujian ReSharper saya maupun yang asli untuk MSTEST di Visual Studio 2017.

Sebaliknya, klik kanan file data Anda, dan pilih properti . Pilih Salin ke direktori keluaran: Selalu .

Sekarang dalam pengujian Anda, lakukan ini. Direktori hanyalah direktori file yang berhubungan dengan proyek uji. Mudah.

    [TestMethod()]
    public void ParseProductsTest()
    {
        // Arrange
        var file = @"Features\Products\Files\Workbook_2017.xlsx";
        var fileStream = File.Open(file, FileMode.Open);
        // etc.
    }

Ini tampaknya berfungsi dengan baik dengan sistem build dan pengujian otomatis.

Jess
sumber
1

Karena saya selalu menemukan atribut DeploymentItem berantakan, saya melakukan penerapan file tersebut dengan menggunakan skrip pasca-build. - Pastikan file yang ingin Anda salin memiliki properti Salin Selalu disetel. - Ubah skrip post-build proyek pengujian Anda untuk menyalin file dari folder target build (Bin \ Debug) ke lokasi tempat pengujian Anda mengharapkannya.

Ismail Hawayel
sumber
1

Coba ini untuk VS2010. Jadi Anda tidak perlu menambahkan DeployItems untuk setiap tif
Hapus file

[DeploymentItem(@"files\valid\valid_entries.txt")]  
[DeploymentItem(@"files\tif\")]  

Tambahkan konfigurasi pengujian.
- klik kanan pada node solusi di explorer solusi
- Tambah -> Item Baru ...
- Pilih node Pengaturan Tes di sebelah kiri, pilih item di sebelah kanan
- Klik Tambah

Sebut saja mis TDD

Pilih di TDDbawah TestMenu>Edit Testsettings .

Klik pada Deployment. Aktifkan dan kemudian Tambahkan file dan direktori yang Anda inginkan. Akan ada jalur relatif ke solusi. File akan disimpan. File aslinya misalnya di sini:

D:\Users\Patrik\Documents\Visual Studio 2010\Projects\DCArrDate\WebMVCDCArrDate\Trunk\WebMVCDCArrDate\Authority.xml  

Ketika saya menjalankan pengujian unit saya, itu akan disalin ke

D:\Users\Patrik\Documents\Visual Studio 2010\Projects\DCArrDate\WebMVCDCArrDate\Trunk\WebMVCDCArrDate.Tests\bin\Debug\TestResults\Patrik_HERKULES 2011-12-17 18_03_27\Authority.xml  

dalam kode tes saya menyebutnya dari:

[TestMethod()]
public void Read_AuthorityFiles_And_ParseXML_To_Make_Dictonary()  
{  
  string authorityFile = "Authority.xml";  
  var Xmldoc = XDocument.Load(authorityFile);  

Tidak perlu memilih Salin Selalu; letakkan file-file tersebut di testproject; tambahkan jalur hardcode di testcode. Bagi saya, solusi ini bekerja paling baik. Saya mencoba dengan DeploymentItem, salin selalu tetapi tidak sesuai dengan keinginan saya.

Patrik Lindström
sumber
1

Bagi mereka yang lebih suka menghindari kekacauan DeploymentItem dan mengambil pendekatan yang disarankan oleh @Martin Peck (jawaban yang diterima), Anda dapat menggunakan kode berikut untuk mengakses konten sumber daya yang disematkan:

public string GetEmbeddedResource(string fullyQulifiedResourceName)
{
    var assembly = Assembly.GetExecutingAssembly();
    // NOTE resourceName is of the format "Namespace.Class.File.extension";

    using (Stream stream = assembly.GetManifestResourceStream(fullyQulifiedResourceName))
    using (StreamReader reader = new StreamReader(stream))
    {
        string result = reader.ReadToEnd();
    }
}

Untuk detailnya, lihat SO Thread ini

Sudhanshu Mishra
sumber
1
Saya mengalami masalah dengan Assembly.GetExecutingAssembly () ketika berjalan di server build -> itu akan mengembalikan runner pengujian alih-alih perakitan pengujian yang sebenarnya. Mendapatkan assembly dengan merefleksikannya dari tipe tetap di testassembly (misalnya testclass Anda) menyelesaikan ini untuk saya.
Arno Peters
1

Bagi saya, akar penyebabnya adalah sesuatu yang sama sekali berbeda: Kode produksi yang dijalankan oleh pengujian saya mengganti nama dan / atau menghapus file pengujian .xml yang sedang diterapkan.

Oleh karena itu, ketika saya akan menjalankan pengujian saya satu per satu, mereka akan lulus, tetapi ketika menjalankan semuanya bersama-sama, pengujian kedua dan selanjutnya akan gagal dengan kesalahan "file tidak ditemukan" (yang awalnya saya salah didiagnosis sebagai DeploymentItem atribut tidak berfungsi).

Solusi saya adalah meminta setiap metode pengujian membuat salinan file yang digunakan (menggunakan teknik ini ), dan kemudian menguji kode produksi menggunakan file yang disalin, bukan yang asli.

Jon Schneider
sumber
1

Kami telah menghabiskan banyak waktu dengan masalah Deployment item untuk menyelesaikannya dalam unittest run lokal dan teamcity unittest reun juga. Ini tidak mudah.

Alat yang sangat bagus untuk men-debug masalah ini adalah ProcessExplorer . Menggunakan penjelajah proses, Anda dapat memeriksa di mana Visual Studio mencari item penyebaran dan membuat koreksi pada proyek. Cukup filter semua operasi file di mana path berisi nama file deploymentitem Anda dan Anda akan melihatnya.

Tomas Kubes
sumber
Saya tahu ini adalah jawaban yang sangat lama, tetapi jika Anda dapat menguraikan cara Anda menggunakan ProcessExplorer, itu akan sangat membantu. Saya tidak melihat cara melihat operasi file sama sekali, apalagi memfilternya ...
David
1

Selain atribut Deployment yang perlu diperiksa, saya menemukan hal lain tentang atribut DeploymentItem.

[TestMethod()]
[DeploymentItem("folder\subfolder\deploymentFile.txt")]
public void TestMethod1()
{
   ...
}

DeploymentFile.txt Anda harus relatif terhadap file solusi dan bukan testfile.cs.

masukkan deskripsi gambar di sini

Paven sendiri
sumber
Saya akhirnya mendapatkan ini berfungsi dengan membuat sumber DeploymentItem saya relatif terhadap proyek pengujian. Jadi saya memiliki proyek dalam solusi saya, "Service.Tests". Di bawah sana saya memiliki folder "FilesForTests" yang memiliki file yang ingin saya salin. Saya dulu [DeploymentItem(@"FilesForTests\MyFile.txt", "FilesForTests")]. Saya pikir kita mengatakan hal yang sama?
David
1

Saya telah mengerjakan ini di VS2013. Temuan saya untuk membuat ini berfungsi:

  • Salin ke direktori keluaran harus disetel ke Salin jika Lebih Baru / Salin Selalu: WAJIB.
  • "Enable Deployment" di .TestSettings: NOT REQUIRED. Saya mendapatkan ini berfungsi tanpa file .TestSettings sama sekali.
  • Menentukan folder sebagai parameter ke-2: OPTIONAL. Membentuk tata letak folder keluaran, berfungsi dengan baik tanpa.
  • SPASI dalam nama file: ini membuat saya pusing - file tidak pernah disalin. Menghapus spasi memperbaiki ini. Belum melihat karakter pelarian.

Sebuah tip saya juga belajar dengan cara yang sulit: jangan lupa untuk menambahkan atribut ini ke tes masing-masing individu. File menyalin pada pengujian yang dikaitkan pertama dalam testrun, tetapi tetap hilang ketika urutan pengujian berubah dan pengujian tanpa atribut mencoba menemukan file tersebut terlebih dahulu.

Arno Peters
sumber
Mencoba semuanya di sini sebelum mendapatkan jawaban Anda yang merupakan yang terakhir. Pelakunya: SPACES IN THE FILENAME! Keterangan yang bagus.
joelmdev
1
Menggunakan Visual Studio 2019. "Salin jika lebih baru" memperbaikinya. Saya benci "Salin selalu" karena memaksa proyek untuk membangun kembali pada banyak skenario seperti debug atau build tambahan.
Gerardo Grignoli
Sepakat. Saya telah memperbarui jawaban saya untuk menyertakan Salin jika Lebih Baru.
Arno Peters
0

"Gotcha" besar saya adalah cara DeploymentItem menangani direktori. Saya menggunakan versi dua parameter dengan keduanya sebagai jalur direktori yang berisi subdirektori yang ingin saya terapkan. Awalnya saya tidak menyadari bahwa itu hanya menyalin barang-barang di ROOT direktori dan bukan seluruh struktur folder rekursif!

Saya pada dasarnya memiliki [DeploymentItem (@ "Foo \", @ "Foo \")] dan mengharapkannya untuk menerapkan Foo \ Bar saya. Saya secara khusus harus mengubahnya menjadi [DeploymentItem (@ "Foo \ Bar \", @ "Foo \ Bar \")] dan sekarang berfungsi seperti pesona.

StalePhish
sumber
0

Saya juga menghadapi masalah serupa. Saya memiliki semua langkah yang disebutkan di atas tetapi masih belum berhasil. Saya menggunakan VS2010. Kemudian saya menemukan bahwa $ Menu> Test> Select Active Test Setting> Trace and Test impact telah dipilih. Ini mulai berfungsi setelah saya mengubah Jejak dan uji dampak ke Lokal . Halaman ini berisi informasi yang sangat berguna tentang menyalin file ke folder hasil tes, saya merasa ingin menambahkan pengalaman ini juga.

MJK
sumber