DeploymentItem属性存在问题


94

我目前正在维护用C#.net编写的“旧”系统,删除一些过时的功能并进行一些重构。谢谢上帝,以前的家伙写了一些单元测试(MSTests)。我对JUnit测试相当满意,但对MSTest并没有做太多事情。

测试方法具有一个DeploymentItem属性,该属性指定一个文本文件(该文件由要测试的业务逻辑方法解析)和第二个属性,DeploymentItem其中仅指定了一个路径,其中包含一堆也必须部署的TIF文件。

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

测试以前可以进行,但是现在我不得不更改\ files \ tif目录中包含的TIF文件的名称。根据规则,TIF文件名必须匹配某个模式,该模式也由该ExistsTifTest()方法检查。现在,我不得不更改文件名以使其适应新要求,并且突然之间,不再像以前那样部署TIF文件。

有人可以给我提示为什么会发生这种情况或可能是什么原因吗?如果在测试方法中具有相应DeploymentItem属性的\ files \ valid \目录中的“ valid_entries.txt”旁边添加一个新的文本文件,例如“ my2ndTest.txt”,也会发生相同的情况。文件未部署?

我现在通过直接在testrunco​​nfig中定义部署路径来部署映像,但是我想了解为什么会发生这些事情,或者为什么为什么我的新文件“ my2ndTest.txt”没有被部署,而其他文件却被部署了。


2
这里的一个大难题是要意识到DeploymentItemAttribute中指定的所有项目都将被复制到测试程序运行所在的位置。换句话说,如果您希望它可以保留您的目录结构,那么您将很不幸。如果需要将其复制到特定目录,请使用两个参数DeploymentItem(source,outputDir)版本。仅供参考-您可以通过将System.Console.WriteLine(System.Environment.CurrentDirectory)放到其中一个测试中,来了解MsTest的文件运行位置。NCrunch没有这个问题!
CodeMonkeyKing

Answers:


112

DeploymentItem 有点混乱。

解决方案中的每个文件在VS.NET中都有一个“复制到输出文件夹”设置。为了使文件进入输出文件夹,您需要将此文件设置为“始终复制”(或类似名称)。

检查是否已为新文件设置了此设置。如果没有此设置,则文件将不会被复制到输出文件夹,也无法从输出文件夹部署到MSTest进行填充的文件夹。

就个人而言,如果我有单元测试所需的文件,我发现将这些文件作为资源嵌入到程序集中,并在测试过程中使程序集“解包”是一种更可预测的工作方式。YMMV。

注意:这些评论基于我对VS2010的经验。对我的答案的评论表明,这不是VS2012的问题。我仍然不赞成这样的评论,即使用嵌入式资源所涉及的“魔术”更少,并且对我而言,使单元测试的“安排”阶段更加明确。


3
复制到输出目录永远不会影响MSTest部署文件的方式。这个答案是不正确的。
2011年

19
在VS2010 Premium上,进行此更改(且无其他更改)导致文件被部署。因此,我根据实际证据得出结论,它确实会影响MsTest部署。
JonStonecash 2011年

1
同意 我已经看到这个单一的变化使DeploymentItem皱起来了。
马丁·派克

2
在VS2012上似乎不再需要此功能。我的部署项目的“复制到输出文件夹”设置为“不复制”。
Mike

31
当无法复制您提供的单个文件时,DeploymentItem不会发出通知就很棒。

74

在VS2010中,我的Local.testsettings未选中“启用部署”,并且DeploymentItem属性不起作用。我检查了一下,一切正常。我希望这有帮助!


2
多年来,我一直试图将头撞在砖墙上,以使其正常工作....谢谢!
mat-mcloughlin 2011年

12
我认为如果框架发出警告,如果关闭此设置将忽略DeploymentItem属性,那就太好了。我还在桌子上留下了漂亮的凹痕。
艾伦·麦比

2
请注意,Local.testsettings位于“解决方案项目”中
Matthew Lock

我还必须添加包含要部署到Local.testsettings的项目的目录:i.imgur.com/p1z3m9R.png
马修·洛克

在2018年使用VS2017选中``启用部署''仍然是此问题的解决方案。现在可悲的是,Visual Studio仍然发出警告。因此,感谢您的解决方案。
唐H

19

我也遇到过类似的问题,但是我为此找到了简单的三步解决方案:

假设您的文件夹结构如下所示: SolutionFolder\ TestProjectFolder\ SubFolder\

  1. 转到“解决方案项目/Local.testsettings”>“部署”>选中“启用部署”
  2. 如果使用的是VS2010,请确保要部署的所有文件的“复制到输出文件夹”属性都设置为“始终复制”或“如果更新则复制”
  3. 使用以下任一属性为您的TestMethod属性:
    • [DeploymentItem(@"TestProjectFolder\SubFolder")]将所有内容部署<SubFolder>到“测试运行”目录
    • [DeploymentItem(@"TestProjectFolder\SubFolder", "TargetFolder")] 将的所有内容部署<SubFolder><TargetFolder>Test Run目录中

关于MSTest的最后一点说明(至少对于VS2010):

如果您希望的<TargetFolder>名称与相同<SubFolder>,则使用[DeploymentItem(@"SubFolder", @"SubFolder")]将失败,因为MSTest运行程序遇到了一个奇怪的情况。这就是为什么您应该<SubFolder><TestProjectFolder>as前面加上前缀:[DeploymentItem(@"TestProjectFolder\SubFolder", @"SubFolder")]


有关SubFolder命名失败的注释是一个珍宝。
RJ Lohan 2014年

1
VS 2015似乎有所不同。我需要删除DeploymentItem属性中的“ TestPojectFolder”部分。
uli78

15

为了有希望帮助其他人,我在这里尝试了所有建议,但仍然没有复制我的部署项目。

我要做的(如这里的建议)是向DeploymentItem属性添加第二个参数:

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

10

如果进入.testrunco​​nfig文件并在部署下取消选中“启用部署”,则测试将在其正常位置运行,并且一切将像在单元测试之外运行应用程序时一样工作。


也有一些问题。作为PM,我无法使用开发人员使用的所有工具。在这种情况下,ReSharper正确复制了文件,而MSTest未能正确复制。->开发正常时我遇到了错误。更改为“测试->编辑测试设置->本地设置->部署”,包括有问题的文件,供我的MSTest使用。
sonstabo 2011年

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中。如果我所有的测试都使用相同的支持工件怎么办?我猜我应该跨数十种测试方法复制并粘贴装饰器?荒谬。
Ryanman '16

5

在尝试了此处列出的所有其他建议之后,我仍然不知道发生了什么。最终,我发现在“测试/测试设置”菜单下没有选择任何设置文件,这意味着未启用“部署”。我单击“测试/测试设置/选择测试设置文件”菜单项,选择Local.TestSettings文件,然后一切正常。


4

不确定这是否能回答问题,但可能会有所帮助。首先,我发现必须选中“启用部署”框才能使部署正常工作。其次,文档说源路径“相对于项目路径”,起初我指的是项目文件夹。实际上,它似乎是指build输出文件夹。因此,如果我有一个名为“ TestFiles”的项目文件夹,并且其中有一个名为的文件,则Testdata.xml使用该属性将无法正常工作:

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

我可以标记 Testdata.xml文件Copy Always,以便构建将副本放置在输出文件夹(例如Debug\TestFiles\TestData.xml)下。然后,部署机制将找到TestFiles\Testdata.xml相对于构建输出位于该路径()的文件副本。或者,我可以这样设置属性:

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

部署机制将找到原始文件。因此,无论哪种方法都有效,但我注意到使用Copy Always I有时会遇到在项目中编辑app.config文件时遇到的相同问题-如果我不更改代码或不强制重建,则不会触发复制标记为在构建时复制。


相对路径对我来说是个问题,这已经解决了。我根据测试的运行方式添加了2套DeploymentItem语句。
Ed Bayiates

3

我首先禁用了部署标志。但是即使启用了它,由于某种未知的原因,即使目标DLL也不会被复制。偶然地,我打开了“测试运行”窗口,并杀死了之前的所有运行,然后神奇地发现,在下次运行时,我在测试文件夹中需要的所有DLL和文件……非常令人困惑。


2

我在尝试部署文件时遇到了很大的问题-尝试上述所有建议。

然后我关闭了VS2010;重新启动它,加载解决方案,一切正常。(!)

我做了一些检查;在local.TestSetting上设置“启用部署”标志后,您不应简单地从“测试结果”窗口中重新运行测试。您必须从UI中删除以前的测试运行,例如通过运行其他测试或重新打开解决方案。


2

不要使用 DeploymentItem

正确设置非常困难,并且无法与我的ReSharper测试运行程序或Visual Studio 2017中用于MSTEST的本地运行程序一起使用。

而是右键单击您的数据文件,然后选择properties。选择复制到输出目录:始终

现在在您的测试中,执行此操作。该目录只是相对于测试项目的文件目录。简单。

    [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

选择TDDTestMenu>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

我们通过部署项目问题花费了很多时间来解决本地单元测试运行和teamcity单元测试重新运行中的问题。这不简单。

调试此问题的一个很好的工具是ProcessExplorer。使用流程浏览器,可以检查Visual Studio在哪里搜索部署项目并更正项目。只需过滤所有文件操作,其中路径包含您的deploymentitem文件名,您将看到它。


我知道这是一个非常古老的答案,但是如果您能够详细说明如何使用ProcessExplorer,那将很有帮助。我根本看不到如何查看文件操作,更不用说过滤它们了……
David

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文件就可以工作了。
  • 将文件夹指定为第二个参数:可选。调整输出文件夹的布局,如果没有,效果很好。
  • 文件名中的空格:这让我头疼-文件从未被复制过。删除空间固定此。尚未研究转义字符。

我还从中学到了一个技巧:不要忘记将此属性添加到每个测试中。该文件在testrun中的第一个属性测试中复制,但是在更改测试顺序并且非属性测试尝试首先查找文件时仍然丢失。


在获得答案之前,先尝试了这里的所有内容,这是最后一个。罪魁祸首:文件名中的空格!好的标注。
joelmdev

1
使用Visual Studio2019。“如果更新,则进行复制”对其进行了修复。我讨厌“总是复制”,因为它会迫使项目在很多情况下(例如调试或增量构建)进行重建。
Gerardo Grignoli

同意 我已经将答案更新为包括“如果较新则复制”。
亚诺·彼得斯

0

我最大的“陷阱”是DeploymentItem处理目录的方式。我使用的是两参数版本,两者都作为包含我要部署的子目录的目录路径。最初我没有意识到它只复制目录根目录中的内容,而不复制整个递归文件夹结构!

我基本上有[DeploymentItem(@“ Foo \”,@“ Foo \”))],并期望它部署我的Foo \ Bar。我特别必须将其更改为[DeploymentItem(@“ Foo \ Bar \”,@“ Foo \ Bar \”))],现在它就像一个吊饰一样工作。


0

我也遇到过类似的问题。我已完成上述所有步骤,但仍然没有运气。我正在使用VS2010。然后我发现选择了$菜单>测试>选择活动测试设置>跟踪和测试影响 。在我更改“跟踪”并测试对Local的影响之后,它开始工作。该页面包含有关将文件复制到测试结果文件夹的非常有用的信息,我也希望增加这种体验。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.