DeploymentItem属性的问题

时间:2009-05-19 14:55:24

标签: c# visual-studio unit-testing mstest deploymentitem

我目前正在维护一个用C#.net编写的“旧”系统,删除一些过时的功能并进行一些重构。感谢上帝,前一个人写了一些单元测试(MSTests)。我对JUnit测试非常熟悉,但对MSTests没有太多帮助。

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

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

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

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

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

19 个答案:

答案 0 :(得分:102)

DeploymentItem有点乱。

解决方案中的每个文件都将在VS.NET中具有“复制到输出文件夹”设置。您需要将其设置为“始终复制”(或类似)才能将文件放入输出文件夹。

检查您是否为新文件设置了此设置。如果你没有这个设置,那么文件将不会被复制到输出文件夹,然后它们无法从输出文件夹部署到MSTest所做的文件夹。

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

注意:这些评论是基于我对VS2010的体验。对我的回答的评论表明这不是VS2012的问题。我仍然坚持认为使用嵌入式资源不那么“神奇”,对我来说,使我的单元测试的“安排”阶段更加明确。

答案 1 :(得分:74)

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

答案 2 :(得分:17)

我也面临类似的问题,但我找到了简单的3步解决方案:

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

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

    如果您希望<TargetFolder><SubFolder>具有相同的名称,则在MSTest跑步者遇到愚蠢的边缘情况时,使用[DeploymentItem(@"SubFolder", @"SubFolder")]会无声地失败。这就是为什么你应该在<SubFolder>前加<TestProjectFolder>作为前缀:[DeploymentItem(@"TestProjectFolder\SubFolder", @"SubFolder")]

答案 3 :(得分:14)

希望能帮助其他人:我在这里尝试了所有建议,并且仍然我的部署项目未被复制。

我必须做的事情(as suggested here)是在DeploymentItem属性中添加第二个参数:

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

答案 4 :(得分:10)

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

答案 5 :(得分:8)

这可能与您的确切问题无关,但这里有一些我在[DeploymentItem]属性中​​找到的提示。

  1. 复制到输出目录应设置为“始终复制”。
  2. 与[TestInitialize]属性一起使用 NOT

    [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()
        {
            ...
        }
    

答案 6 :(得分:5)

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

答案 7 :(得分:4)

不确定这是否完全回答了这个问题,但它可能有所帮助。 首先,我发现必须检查“启用部署”框以使部署工作。 其次,doc说源路径是“相对于项目路径”,起初我指的是项目文件夹。实际上,它似乎是指构建输出文件夹。 因此,如果我有一个名为“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文件时遇到的同样问题 - 如果我不更改代码或强制重建,则不会触发复制标记为在构建时复制的文件。

答案 8 :(得分:3)

我首先禁用了部署标志。但即使在我启用它之后,由于某种未知的原因,甚至没有任何目标DLL也会被复制。无意中我打开了测试运行窗口并杀死了所有以前的运行,并且奇怪地发现我在下一次运行时在测试文件夹中需要的所有DLL和文件......非常令人困惑。

答案 9 :(得分:2)

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

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

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

答案 10 :(得分:1)

尝试使用VS2010。所以你不需要为每个tif添加DeployItems

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

添加测试配置   - 右键单击​​解决方案资源管理器中的解决方案节点   - 添加 - &gt;新物品......
  - 选择左侧的“测试设置”节点,选择右侧的项目   - 单击添加

称之为TDD

TDD&gt;下选择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  

在testcode中我从以下地方调用它:

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

无需选择“始终复制”;把文件放在testproject中;在测试代​​码中添加硬编码路径。对我来说这个解决方案效果最好我尝试使用DeploymentItem,总是复制,但这不是我喜欢的。

答案 11 :(得分:1)

由于我总是发现DeploymentItem属性一团糟,我使用post-build脚本来部署这些文件。 - 确保要复制的文件具有“始终复制”属性集。 - 修改测试项目的构建后脚本,将文件从构建目标文件夹(Bin \ Debug)复制到测试期望的位置。

答案 12 :(得分:1)

我在VS2013中一直在研究这个问题。我的调查结果是:

  • 复制到输出目录应设置为Copy Always:MANDATORY。
  • &#34;启用部署&#34; in .TestSettings:不需要。我得到了这个工作 没有.TestSettings文件。
  • 将文件夹指定为第二个参数:OPTIONAL。塑造输出文件夹布局,无需正常工作。
  • 文件名中的空格:这让我很头疼 - 文件从未复制过。删除固定的空格。哈文还没有看过逃脱角色。

小费我也学到了很多方法:不要忘记将这个属性添加到每个单独的测试中。该文件在testrun中的第一个属性测试上复制,但在测试顺序发生变化且非属性测试试图首先找到该文件时仍然丢失。

答案 13 :(得分: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();
    }
}

有关详细信息,请参阅this SO Thread

答案 14 :(得分:1)

对我来说,根本原因完全不同:我的测试所运行的生产代码是重命名和/或删除正在部署的.xml测试文件。

因此,当我单独运行我的测试时,它们会通过,但是当它们一起运行时,第二次和后续测试将失败并显示“找不到文件”错误(我最初将其误诊为{{ 1}}属性不起作用。)

我的解决方案是让每个单独的测试方法复制已部署的文件(使用this technique),然后让测试的生产代码使用复制的文件而不是原始文件。

答案 15 :(得分:1)

除了需要检查的Deployment属性外,我还发现了有关DeploymentItem属性的其他内容。

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

您的deploymentFile.txt需要相对于解决方案文件而不是testfile.cs。

enter image description here

答案 16 :(得分:0)

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

我基本上有[DeploymentItem(@“Foo \”,@“Foo \”)],并且期待它部署我的Foo \ Bar。我特别需要将它更改为[DeploymentItem(@“Foo \ Bar \”,@“Foo \ Bar \”)],现在它就像一个魅力。

答案 17 :(得分:0)

我也遇到过类似的问题。我已经完成了上面提到的所有步骤,但仍然没有运气。我正在使用VS2010。然后我发现 $ Menu&gt;测试&gt;选择活动测试设置&gt;已选择跟踪和测试影响。在我将Trace和测试影响更改为 Local 之后,它开始工作了。此页面包含有关将文件复制到测试结果文件夹的非常有用的信息,我也想添加这种体验。

答案 18 :(得分:0)

不要使用DeploymentItem

设置正确非常困难,它不能与我的ReSharper测试运行器一起使用,也不适用于Visual Studio 2017中的MSTEST本机。

相反,右键单击您的数据文件,然后选择属性。选择复制到输出目录:始终

现在进行测试,请执行此操作。该目录只是相对于测试项目的文件目录。容易。

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

买者。我不知道这是否适用于自动构建和测试系统。我还没有。