Проблемы с атрибутом DeploymentItem


94

В настоящее время я поддерживаю «старую» систему, написанную на C # .net, удаляя некоторые устаревшие функции и выполняя некоторый рефакторинг. Слава богу, предыдущий парень написал несколько модульных тестов (MSTests). Я вполне доволен тестами JUnit, но пока мало что делал с MSTests.

Методы тестирования имеют DeploymentItemатрибут, определяющий текстовый файл, который анализируется методом бизнес-логики, который тестируется, и второй, в DeploymentItemкотором указан только путь, содержащий кучу файлов TIF, которые также необходимо развернуть.

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

Раньше тесты работали, но теперь мне пришлось изменить имена файлов TIF, содержащихся в каталоге \ files \ tif. Согласно правилу, имена файлов TIF должны соответствовать определенному шаблону, который также проверяется ExistsTifTest()методом. Теперь мне пришлось изменить имена файлов, чтобы адаптировать их к новым требованиям, и внезапно файлы TIF больше не развертываются, как раньше.

Может кто-нибудь подскажет, почему это происходит или в чем может быть причина? То же самое происходит, если я добавляю новый текстовый файл, например "my2ndTest.txt" рядом с "valid_entries.txt" в каталог \ files \ valid \ с соответствующим атрибутом DeploymentItem в методе тестирования. Файл не развертывается?

Теперь у меня есть развернутые образы, указав путь развертывания непосредственно в testrunconfig, но я хотел бы понять, почему это происходит или почему, например, мой новый файл «my2ndTest.txt» не развертывается, в то время как другие развертываются.


2
Здесь важно понять, что все элементы, указанные в атрибуте DeploymentItemAttribute, будут скопированы в место, откуда запускаются ваши тестовые сборки. Другими словами, если вы надеялись, что он сохранит вашу структуру каталогов, вам не повезет. Если вам нужно скопировать его в конкретный каталог, используйте версию с двумя параметрами DeploymentItem (source, outputDir). FYI - вы можете пойти по старой школе, чтобы узнать, где файлы запускаются для MsTest, добавив System.Console.WriteLine (System.Environment.CurrentDirectory) в один из ваших тестов. У NCrunch этой проблемы не было!
CodeMonkeyKing 01

Ответы:


112

DeploymentItem немного беспорядок.

Каждый файл в вашем решении будет иметь параметр «Копировать в папку вывода» в VS.NET. Вам нужно, чтобы это было «Всегда копировать» (или подобное), чтобы файлы помещались в папку вывода.

Убедитесь, что у вас есть этот набор для новых файлов. Если у вас нет этого набора, файлы не будут скопированы в выходную папку, а затем их нельзя будет развернуть из выходной папки в папку, в которой MSTest делает это.

Лично у меня есть файлы, которые мне нужны для моих модульных тестов, я обнаружил, что встраивание этих файлов в качестве ресурсов в сборку и «распаковка» этой сборки во время тестов - более предсказуемый способ сделать что-то. YMMV.

примечание: эти комментарии основаны на моем опыте работы с VS2010. Комментарии к моему ответу предполагают, что это не проблема VS2012. Я все еще поддерживаю комментарии о том, что использование встроенных ресурсов требует меньше «магии» и для меня делает этап «упорядочения» моих модульных тестов более явным.


3
Копирование в выходной каталог никогда не влияет на то, как MSTest развертывает файлы. Это неверный ответ.
kzu

19
В VS2010 Premium внесение этого изменения (и никаких других изменений) привело к развертыванию файла. Таким образом, я делаю вывод, основываясь на фактических доказательствах того, что это ДЕЙСТВИТЕЛЬНО влияет на развертывание MsTest.
JonStonecash

1
Согласовано. Я видел, как это единственное изменение перевернуло DeploymentItem с ног на голову.
Мартин Пек

2
Кажется, это больше не требуется на VS2012. Мои элементы развертывания развертываются с параметром «Копировать в папку вывода», установленным на «Не копировать».
Майк

31
Замечательно, что DeploymentItem не уведомляет вас, когда не может скопировать единственный файл, который вы ему предоставили.

74

В VS2010 в моих настройках Local.testsettings параметр «Включить развертывание» был снят, а атрибут DeploymentItem не работал. Я проверил, все работает нормально. Надеюсь, это поможет!


2
Я много лет бился головой о кирпичную стену, пытаясь заставить ее работать .... спасибо!
mat-mcloughlin

12
Я думаю, было бы неплохо, если бы фреймворк выдал предупреждение о том, что атрибуты DeploymentItem игнорируются, если этот параметр отключен. Я также сделал красивый вогнутый отпечаток на моем столе.
Алан МакБи - MSFT

2
Обратите внимание, что Local.testsettings находится в элементах решения
Мэтью Лок

Мне также пришлось добавить каталог, содержащий элементы, которые я хотел развернуть, в Local.testsettings также: i.imgur.com/p1z3m9R.png
Мэтью Лок

При использовании VS2017 в 2018 г. установка флажка «Включить развертывание» по-прежнему является решением этой проблемы. И, к сожалению, до сих пор предупреждение от Visual Studio вообще. Так что спасибо за это решение.
Don H

19

У меня тоже были похожие проблемы, но я нашел для этого простое трехэтапное решение:

Предположим, ваша структура папок выглядит так: SolutionFolder\ TestProjectFolder\ SubFolder\

  1. Перейдите в «Элементы решения / Local.testsettings»> «Развертывание»> установите флажок «Включить развертывание».
  2. Если вы используете VS2010, убедитесь, что для всех файлов, которые вы хотите развернуть, свойство «Копировать в папку вывода» установлено на «Всегда копировать» или «Копировать, если новее».
  3. Атрибут TestMethod одним из следующих вариантов:
    • [DeploymentItem(@"TestProjectFolder\SubFolder")]развернуть все содержимое <SubFolder>в каталог Test Run
    • [DeploymentItem(@"TestProjectFolder\SubFolder", "TargetFolder")] развернуть все содержимое , <SubFolder>чтобы <TargetFolder>в каталоге Test Run

И последнее замечание о MSTest (по крайней мере, для VS2010):

Если вы хотите, <TargetFolder>чтобы имя имело то же самое, что и у <SubFolder>, использование не [DeploymentItem(@"SubFolder", @"SubFolder")]приведет к ошибке, так как бегун MSTest попадет в глупый крайний случай. Вот почему вы должны поставить перед <SubFolder>перед <TestProjectFolder>следующим:[DeploymentItem(@"TestProjectFolder\SubFolder", @"SubFolder")]


Замечание об ошибке именования вложенных папок - жемчужина.
RJ Lohan

1
VS 2015 кажется немного другим. Мне нужно было удалить часть «TestPojectFolder» в атрибуте DeploymentItem.
uli78

15

Надеюсь, вы поможете кому-то еще: я попробовал все предложения здесь, но мой элемент развертывания не копировался.

Что мне нужно было сделать ( как предлагается здесь ), так это добавить второй параметр к атрибуту DeploymentItem:

[DeploymentItem(@"UnitTestData\TestData.xml", "UnitTestData")]

10

Если вы войдете в свой файл .testrunconfig и при развертывании снимите флажок «Включить развертывание», тесты будут выполняться в обычном месте, и все будет работать так же, как при запуске приложения вне модульного теста.


Были проблемы и с этим. Как PM у меня нет доступа ко всем инструментам, используемым разработчиками. В этом случае ReSharper правильно скопировал файл, а MSTest не смог этого сделать. -> У меня возникли ошибки, пока разработчик был в порядке. Перейдите на «Тест-> Изменить настройки теста -> Локальные настройки -> Развертывание», включая файл, о котором идет речь, исправив это для моего использования MSTest.
sonstabo

9

Вероятно, это не относится к вашей конкретной проблеме, но вот несколько советов, которые я нашел с атрибутом [DeploymentItem].

  1. Копировать в выходной каталог должен быть установлен на Копировать всегда.

Это НЕ работает , когда используется с [TestInitialize] атрибут

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

Он должен быть на вашем [TestMethod], например

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

    [TestMethod]
    [DeploymentItem("test.xlsx")]
    public void ExcelQuestionParser_Reads_XmlElements()
    {
        ...
    }

1
Это безумно досадное ограничение. Мне кажется, что во многих случаях время развертывания должно быть в Initialize. Что, если во всех моих тестах используются одни и те же вспомогательные артефакты? Полагаю, я должен копировать и вставлять декораторы в десятки методов тестирования? Смешной.
Райанман

5

Попробовав все остальные предложения, перечисленные здесь, я все еще не мог понять, что происходит. Наконец, я обнаружил, что в меню «Тест / Настройки теста» не был выбран файл настроек, что означало, что развертывание не было включено. Я щелкнул по пункту меню Test / Test Settings / Select Test Settings File, выбрал файл Local.TestSettings, после чего все заработало.


4

Не уверен, что это точно отвечает на вопрос, но некоторым это может помочь. Во-первых, я обнаружил, что для работы развертывания необходимо установить флажок «Включить развертывание». Во-вторых, в документе говорится, что исходный путь «относительно пути к проекту», который сначала я принял за папку проекта. Фактически, похоже, это относится к выходной папке сборки. Итак, если у меня есть папка проекта с именем TestFiles и файл в ней с именем Testdata.xml, использование этого атрибута не работает:

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

Я могу пометить Testdata.xmlфайл Copy Always, чтобы сборка поместила копию в папку вывода (например, Debug\TestFiles\TestData.xml). Затем механизм развертывания найдет копию файла, расположенную по этому пути ( TestFiles\Testdata.xml) относительно выходных данных сборки. Или я могу установить атрибут следующим образом:

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

и механизм развертывания найдет исходный файл. Итак, либо работает, но я заметил, что при использовании Copy Alwaysя иногда сталкиваюсь с той же проблемой, что и при редактировании файла app.config в проекте - если я не изменяю код или не принудительно перестраиваю, ничто не запускает копирование файлов, отмеченных как копироваться при сборке.


Относительный путь был для меня проблемой, и это исправило ее. Я добавил 2 набора операторов DeploymentItem в зависимости от того, как выполнялись тесты.
Эд Байятс

3

Сначала у меня был отключен флаг развертывания. Но даже после того, как я его включил, по какой-то неизвестной причине даже целевые библиотеки DLL не копировались. Случайно я открыл окно Test Run и убил все предыдущие запуски, и волшебным образом я обнаружил все библиотеки DLL и файлы, которые мне были нужны в тестовой папке при следующем запуске ... Очень запутанно.


2

У меня были огромные проблемы при попытке развернуть файлы - я пробовал все предложения выше.

Затем я закрыл VS2010; перезапустил, загрузил решение и все заработало. (!)

Я проверил; После установки флага «Разрешить развертывание» в local.TestSetting не следует просто повторно запускать тест из окна «Результаты тестирования». Вы должны удалить предыдущий тестовый прогон из пользовательского интерфейса, например, запустив другой тест или повторно открыв свое решение.


2

Не используйте DeploymentItem.

Его очень сложно правильно настроить, и он не работал ни с моим средством запуска тестов ReSharper, ни с собственным для MSTEST в Visual Studio 2017.

Вместо этого щелкните правой кнопкой мыши файл данных и выберите свойства . Выберите Копировать в выходной каталог: Всегда .

Теперь сделайте это в своем тесте. Каталог - это просто каталог файла относительно тестового проекта. Легко.

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

Кажется, это действительно хорошо работает с автоматизированными системами сборки и тестирования.


1

Поскольку я всегда считал атрибут DeploymentItem беспорядочным, я развертываю такие файлы с помощью сценария после сборки. - Убедитесь, что для файлов, которые вы хотите скопировать, задано свойство Копировать всегда. - Измените сценарий после сборки тестового проекта, чтобы скопировать файлы из целевой папки сборки (Bin \ Debug) в то место, где их ожидает тест.


1

Попробуйте это для VS2010. Таким образом, вам не нужно добавлять DeployItems для каждого tif
Удалите

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

Добавьте тестовую конфигурацию.
- щелкните правой кнопкой мыши узел решения в обозревателе решений.
- Добавить -> Новый элемент ...
- Выберите узел Параметры теста слева, выберите элемент справа
- Нажмите Добавить

Назовите это например TDD

Выбрать TDDподTestMenu >Edit Testsettings .

Щелкните развертывание. Включите его, а затем добавьте нужные файлы и каталоги. Будет путь относительно решения. Файлы будут помещены. Исходный файл, например, здесь:

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

Когда я запускаю свой модульный тест, он копируется в

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  

в тестовом коде я вызываю его из:

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

Нет необходимости выбирать «Всегда копировать»; поместить файлы в тестпроект; добавить жестко заданные пути в тестовый код. Для меня это решение сработало лучше всего. Я пробовал использовать DeploymentItem, копировать всегда, но мне это не понравилось.


1

Для тех, кто предпочитает избегать беспорядка DeploymentItem и использовать подход, предложенный @Martin Peck (принятый ответ), вы можете использовать следующий код для доступа к содержимому встроенного ресурса:

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();
    }
}

Подробнее см. Эту тему SO


1
У меня были проблемы с Assembly.GetExecutingAssembly () при запуске на сервере сборки -> он возвращал тестовый бегун вместо фактической тестовой сборки. Получение сборки путем отражения ее от фиксированного типа в тестовой сборке (например, вашего тестового класса) решило это для меня.
Арно Петерс

1

Для меня основной причиной было нечто совершенно иное: производственный код, выполняемый моими тестами, переименовал и / или удалил развернутый тестовый файл .xml.

Поэтому, когда я запускал свои тесты по отдельности, они проходили бы успешно, но при запуске их всех вместе второй и последующие тесты завершались неудачно с ошибками «файл не найден» (которые я изначально ошибочно идентифицировал как DeploymentItem неработающий атрибут).

Мое решение заключалось в том, чтобы каждый отдельный метод тестирования делал копию развернутого файла (используя эту технику ), а затем тестируемый производственный код использовал скопированный файл вместо оригинала.


1

Мы потратили много времени на проблему с элементами развертывания, чтобы решить ее в ходе локального unittest и повторного запуска teamcity unittest. Это не легко.

Очень хороший инструмент для отладки этой проблемы - ProcessExplorer . Используя обозреватель процессов, вы можете проверить, где Visual Studio ищет элементы развертывания, и внести исправления в проект. Просто отфильтруйте все операции с файлами, где путь содержит имя файла развертывания, и вы его увидите.


Я знаю, что это очень старый ответ, но если вы сможете подробнее рассказать, как вы используете ProcessExplorer, это будет полезно. Я вообще не вижу, как просматривать файловые операции, а тем более фильтровать их ...
Дэвид

1

Помимо атрибута Deployment, который необходимо проверить, я обнаружил кое-что еще об атрибуте DeploymentItem.

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

Ваш deploymentFile.txt должен относиться к файлу решения, а не к testfile.cs.

введите описание изображения здесь


Наконец, я получил эту работу, установив источник DeploymentItem относительно тестового проекта. Итак, у меня в решении есть проект «Service.Tests». Там у меня есть папка FilesForTests, в которой есть файлы, которые я хочу скопировать. Я использовал [DeploymentItem(@"FilesForTests\MyFile.txt", "FilesForTests")]. Я думаю, мы говорим то же самое?
Дэвид

1

Я работал над этим в VS2013. Мои выводы, чтобы заставить это работать:

  • Копировать в выходной каталог должен быть установлен на Копировать, если более новый / Копировать всегда: ОБЯЗАТЕЛЬНО.
  • «Включить развертывание» в .TestSettings: НЕ ТРЕБУЕТСЯ. У меня это работает вообще без файла .TestSettings.
  • Указание папки как 2-го параметра: ДОПОЛНИТЕЛЬНО. Формирует макет выходной папки, отлично работает без.
  • ПРОБЕЛЫ в имени файла: это вызвало у меня головную боль - файл никогда не копировался. Это исправлено удалением пробелов. Еще не заглядывал в escape-символы.

Совет, который я усвоил на собственном горьком опыте: не забывайте добавлять этот атрибут к каждому отдельному тесту. Файл копируется при первом атрибутированном тесте в тестовом прогоне, но остается отсутствующим, когда порядок тестов изменился и тесты без атрибутов попытались найти файл первыми.


Пробовали все здесь, прежде чем перейти к своему последнему ответу. Виновник: ПРОБЕЛЫ В ИМЕНИ ФИЛЕНА! Хорошая выноска.
joelmdev

1
Использование Visual Studio 2019. Исправлено "Копировать, если новее". Я ненавижу «Копировать всегда», потому что это заставляет проект перестраиваться во многих сценариях, таких как отладка или инкрементная сборка.
Херардо Гриньоли

Согласовано. Я обновил свой ответ, включив "Копировать, если новее".
Арно Петерс

0

Моя большая проблема заключалась в том, как DeploymentItem обрабатывает каталоги. Я использовал двухпараметрическую версию с обеими в качестве пути к каталогу, содержащего подкаталоги, которые я хотел развернуть. Первоначально я не понимал, что он копирует только файлы из ROOT каталога, а не всю рекурсивную структуру папок!

У меня в основном был [DeploymentItem (@ "Foo \", @ "Foo \")], и я ожидал, что он развернет мой Foo \ Bar. Мне специально пришлось изменить его на [DeploymentItem (@ "Foo \ Bar \", @ "Foo \ Bar \")], и теперь он работает как шарм.


0

Я тоже сталкивался с подобными проблемами. У меня есть все шаги, упомянутые выше, но все равно не повезло. Я использую VS2010. Затем я обнаружил, что было выбрано $ Menu> Test> Select Active Test Setting> Trace and Test impact . Он начал работать после того, как я изменил Trace and test impact на Local . Эта страница содержит очень полезную информацию о копировании файлов в папку с результатами тестирования, я считаю, что добавить и этот опыт.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.