【问题标题】:Problems with DeploymentItem attributeDeploymentItem 属性的问题
【发布时间】:2010-10-27 08:44:45
【问题描述】:

我目前正在维护一个用 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”没有被部署而其他文件做。

【问题讨论】:

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

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


【解决方案1】:

DeploymentItem 有点乱。

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

检查您是否已为新文件设置了此设置。如果您没有此设置,则文件不会被复制到输出文件夹,然后它们无法从输出文件夹部署到 MSTest 执行它的文件夹。

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

注意:这些 cmets 是基于我对 VS2010 的经验。对我的回答的评论表明这不是 VS2012 的问题。我仍然支持 cmets 使用嵌入式资源涉及更少的“魔法”,并且对我来说,使我的单元测试的“安排”阶段更加明确。

【讨论】:

  • 复制到输出目录永远不会影响 MSTest 部署文件的方式。这个答案不正确。
  • 在 VS2010 Premium 上,进行此更改(并且没有其他更改)会导致文件部署。因此,我根据实际证据得出结论,它确实会影响 MsTest 部署。
  • 同意。我已经看到这个单一的变化让 DeploymentItem 皱起了眉头。
  • 这似乎不再需要在 VS2012 上。我的部署项目正在部署,“复制到输出文件夹”设置为“不复制”。
  • 当 DeploymentItem 无法复制您提供的单个文件时,它不会通知您,这很棒。
【解决方案2】:

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

【讨论】:

  • 多年来我一直在用头撞砖墙,试图让它发挥作用....谢谢!
  • 我认为如果框架发出警告,如果此设置关闭,则 DeploymentItem 属性将被忽略,这会很好。我还在我的桌子上放了一个很好的凹印。
  • 请注意 Local.testsettings 在解决方案项中
  • 我还必须将包含我想要部署的项目的目录添加到 Local.testsettings 中:i.imgur.com/p1z3m9R.png
  • 在 2018 年使用 VS2017 检查“启用部署”仍然是解决此问题的方法。可悲的是,现在仍然来自 Visual Studio 的警告。所以感谢这个解决方案。
【解决方案3】:

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

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

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

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

如果您希望 <TargetFolder><SubFolder> 具有相同的名称,则使用 [DeploymentItem(@"SubFolder", @"SubFolder")] 将在 MSTest 运行程序遇到一个愚蠢的边缘情况时静默失败。这就是为什么你应该在 <SubFolder> 前加上 <TestProjectFolder> 前缀:[DeploymentItem(@"TestProjectFolder\SubFolder", @"SubFolder")]

【讨论】:

  • 关于子文件夹命名失败的注释是一个宝石。
  • VS 2015 似乎有点不同。我需要删除 DeploymentItem 属性中的“TestPojectFolder”部分。
【解决方案4】:

希望能帮助别人:我尝试了这里的所有建议,仍然我的部署项目没有被复制。

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

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

【讨论】:

    【解决方案5】:

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

    【讨论】:

    • 对此也有一些问题。作为 PM,我无法访问开发人员使用的所有工具。在这种情况下,ReSharper 正确复制了文件,而 MSTest 未能这样做。 --> 我在开发正常时遇到了错误。更改为“测试-> 编辑测试设置-> 本地设置-> 部署”,包括有问题的文件为我的 MSTest 使用修复了这个问题。
    【解决方案6】:

    这可能与您的确切问题无关,但这里有一些我发现的 [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()
        {
            ...
        }
    

    【讨论】:

    • 这是一个非常烦人的限制。我觉得在很多情况下,部署时间应该在 Initialize。如果我所有的测试都使用相同的支持工件怎么办?我想我应该在几十种测试方法中复制和粘贴装饰器?可笑。
    • 你也可以把[DeploymentItem]属性放在类上
    【解决方案7】:

    不要使用DeploymentItem

    很难正确设置,而且它不能与我的 ReSharper 测试运行器一起工作,也不能与 Visual Studio 2017 中 MSTEST 的本机运行程序一起工作。

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

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

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

    这似乎确实适用于自动化构建和测试系统。

    这是解决方案中文件所在位置的图片:

    【讨论】:

    • 不,它是相对于 bin/Debug-directory 的吧?
    • @cederlof 在解决方案中测试文件是相对于项目的。运行测试时,会将内容复制到 bin/Debug。
    【解决方案8】:

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

    【讨论】:

      【解决方案9】:

      不确定这是否能准确回答问题,但它可能会有所帮助。 首先,我发现必须选中“启用部署”框才能使部署工作。 其次,文档说源路径是“相对于项目路径”,起初我认为它是指项目文件夹。实际上,它似乎是指构建输出文件夹。 因此,如果我有一个名为“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 语句。
      【解决方案10】:

      我首先禁用了部署标志。但是即使在我启用它之后,由于某种未知的原因,甚至目标 DLL 都不会被复制。不小心我打开了测试运行窗口并杀死了所有以前的运行,然后神奇地我在下一次运行的测试文件夹中找到了我需要的所有 DLL 和文件......非常混乱。

      【讨论】:

        【解决方案11】:

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

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

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

        【讨论】:

          【解决方案12】:

          对于那些喜欢避免 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

          【讨论】:

          • 我在构建服务器上运行时遇到了 Assembly.GetExecutingAssembly() 的问题 -> 它会返回测试运行程序而不是实际的测试程序集。通过在测试程序集中(例如您的测试类)中反映固定类型来获取程序集为我解决了这个问题。
          【解决方案13】:

          由于我总是发现 DeploymentItem 属性一团糟,因此我使用构建后脚本来部署此类文件。 - 确保您要复制的文件具有 Copy Always 属性集。 - 修改您的测试项目构建后脚本,将文件从构建目标文件夹(Bin\Debug)复制到您的测试所期望的位置。

          【讨论】:

            【解决方案14】:

            在 VS2010 上试试这个。所以你不需要为每个 tif 添加 DeployItems
            删除

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

            添加测试配置。
            - 在解决方案资源管理器中右键单击解决方案节点
            - 添加 -> 新项目...
            - 选择左侧的测试设置节点,选择右侧的项目
            - 点击添加

            叫它例如TDD

            TestMenu 下选择TDD > 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,总是复制,但我不喜欢。

            【讨论】:

              【解决方案15】:

              对我来说,根本原因完全是另外一回事:我的测试执行的生产代码是重命名和/或删除正在部署的 .xml 测试文件。

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

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

              【讨论】:

                【解决方案16】:

                我们在本地单元测试运行和 teamcity 单元测试重新运行中花费了大量时间来解决部署项目问题。这并不容易。

                调试此问题的非常好的工具是ProcessExplorer。使用进程资源管理器,您可以检查 Visual Studio 在哪里搜索部署项并对项目进行更正。只需过滤路径包含您的部署项文件名的所有文件操作,您就会看到它。

                【讨论】:

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

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

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

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

                【讨论】:

                • 我终于通过让我的 DeploymentItem 源与测试项目相关来完成这项工作。所以我的解决方案中有一个项目“Service.Tests”。在那里我有一个文件夹“FilesForTests”,其中包含我要复制的文件。我用[DeploymentItem(@"FilesForTests\MyFile.txt", "FilesForTests")]。我认为我们说的是同一件事?
                【解决方案18】:

                我在 VS2013 中一直致力于此。我的发现让这个工作:

                • 复制到输出目录应设置为如果较新则复制/始终复制:强制。
                • .TestSettings 中的“启用部署”:不需要。我得到了这个工作 根本没有 .TestSettings 文件。
                • 将文件夹指定为第二个参数:可选。塑造输出文件夹布局,没有它也能正常工作。
                • 文件名中的空格:这让我很头疼 - 文件从未被复制。删除空格解决了这个问题。还没有研究转义字符。

                一个小窍门,我也学到了一个艰难的方法:不要忘记将这个属性添加到每个单独的测试中。该文件在 testrun 中的第一个属性测试中复制,但在测试顺序更改并且非属性测试尝试首先找到该文件时仍然丢失。

                【讨论】:

                • 在得到最后一个答案之前在这里尝试了一切。罪魁祸首:文件名中的空格!很好的标注。
                • 使用 Visual Studio 2019。“如果更新则复制”修复了它。我讨厌“总是复制”,因为它会迫使项目在很多情况下重新构建,例如调试或增量构建。
                • 同意。我已经更新了我的答案,包括 Copy if Newer。
                【解决方案19】:

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

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

                【讨论】:

                  【解决方案20】:

                  我也遇到过类似的问题。我有上面提到的所有步骤,但仍然没有运气。我正在使用VS2010。然后我发现选择了 $Menu > Test > Select Active Test Setting > Trace and Test Impact。在我将 Trace 和测试影响更改为 Local 后,它开始工作。这个页面包含了非常丰富的关于将文件复制到测试结果文件夹的信息,我觉得也可以添加这个经验。

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 2014-10-02
                    • 1970-01-01
                    • 2010-10-18
                    • 1970-01-01
                    • 1970-01-01
                    • 2016-07-27
                    • 1970-01-01
                    • 1970-01-01
                    相关资源
                    最近更新 更多