Проблемы с атрибутом 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 в проекте - если я не изменяю код или не принудительно перестраиваю, ничто не запускает копирование файлов, отмеченных как копироваться при сборке.

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

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

Шульц9999
источник
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 \")], и теперь он работает как шарм.

StalePhish
источник
0

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

MJK
источник