关于c#:DeploymentItem属性的问题

Problems with DeploymentItem attribute

我目前正在维护一个用C.NET编写的"旧"系统,删除一些过时的功能并进行一些重构。感谢上帝,前一个家伙写了一些单元测试(MStests)。我对JUnit测试很满意,但对MSTests还没有做太多。

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

1
2
3
4
5
6
7
[TestMethod()]
[DeploymentItem(@"files\valid\valid_entries.txt")]
[DeploymentItem(@"files\tif")]
public void ExistsTifTest()
{
   ...
}

这些测试以前是有效的,但现在我不得不更改files if目录中包含的tif文件的名称。根据规则,tif文件名必须与某个模式匹配,该模式也由ExistsTifTest()方法检查。现在我不得不更改文件名,以便使它们适应新的需求,然后TIF文件就不再像以前那样部署了。

有人能给我一个提示,为什么会发生这种情况,或者原因是什么?如果我在filesvaliddirectory的"valid_entries.txt"旁边添加一个新的文本文件,称为"my2ndtest.txt",并在测试方法上使用相应的deploymentem属性,也会发生同样的事情。文件没有部署?

我现在通过直接在testrunconfig中定义部署路径来部署映像,但我想了解为什么会发生这些事情,或者为什么我的新文件"my2ndtest.txt"在其他文件部署时无法部署。


DeploymentItem有点乱。

解决方案中的每个文件在vs.net中都有一个"复制到输出文件夹"设置。您需要将此设置为"始终复制"(或类似设置),以便将文件放入输出文件夹。

检查你是否有新文件的这套。如果您没有此设置,则文件将不会复制到输出文件夹,并且无法从输出文件夹部署到MSTEST处理它的文件夹。

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

注:这些评论是基于我对VS2010的经验。对我答案的评论表明,这与VS2012无关。我仍然支持使用嵌入式资源所涉及的"魔力"更少的评论,对我来说,这使得单元测试的"安排"阶段更加明确。


在VS2010中,我的local.testsettings未选中"启用部署",DeploymentItem属性不起作用。我检查过了,一切正常。希望这有帮助!


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

假设文件夹结构如下:埃多克斯1〔6〕

  • 转到"solutions items/local.testsettings">"deployment">check"enable deployment"
  • 如果您使用的是VS2010,请确保要部署的任何文件的"复制到输出文件夹"属性设置为"始终复制"或"如果更新则复制"。
  • 将testmethod属性为以下任一项:
    • [DeploymentItem(@"TestProjectFolder\SubFolder")]的所有内容部署到测试运行目录中
    • [DeploymentItem(@"TestProjectFolder\SubFolder","TargetFolder")]的所有内容部署到测试运行目录中的
  • 关于MSTEST的最后一条注释(至少对于VS2010而言):

    如果你想让同名,那么使用[DeploymentItem(@"SubFolder", @"SubFolder")]会自动失败,因为mstest运行程序遇到了一个愚蠢的边缘情况。这就是为什么你应该在前面加上,所以:[DeploymentItem(@"TestProjectFolder\SubFolder", @"SubFolder")]


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

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

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


    如果您进入.testrunconfig文件,并在Deployment下取消选中"启用部署",测试将在其正常位置运行,并且在单元测试之外运行应用程序时,所有操作都会像这样进行。


    这可能与您的确切问题无关,但这里有一些关于[deploymentem]属性的提示。

  • 复制到输出目录应设置为始终复制。
  • 当与[TestInitialize]属性一起使用时,它不起作用

    1
    2
    3
    4
    [TestInitialize]
    [DeploymentItem("test.xlsx")]
    public void Setup()
    {

    它应该在您的[测试方法]上,例如

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
        [TestInitialize]
        public void Setup()
        {
            string spreadsheet = Path.GetFullPath("test.xlsx");
            Assert.IsTrue(File.Exists(spreadsheet));
            ...
        }

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


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


    不确定这是否能准确回答问题,但这可能对一些人有所帮助。首先,我发现必须选中"启用部署"框才能使部署工作。第二,Doc说源路径是"相对于项目路径",起初我认为它是指项目文件夹。实际上,它似乎引用了构建输出文件夹。因此,如果我有一个名为"testfiles"的项目文件夹和一个名为Testdata.xml的文件,那么使用这种方式的属性将不起作用:

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

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

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

    部署机制会找到原始文件。所以这两种方法都有效,但我注意到使用Copy Always时,我偶尔会遇到与在项目中编辑app.config文件时相同的问题——如果我不更改代码或强制重新生成,则不会触发复制标记为在生成时复制的文件。


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


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

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

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


    我在VS2013中一直在研究这个问题。我的发现是:

    • 复制到输出目录应设置为始终复制:强制。
    • .testsettings:中的"启用部署"不是必需的。我有这个工作完全没有.testsettings文件。
    • 将文件夹指定为第二个参数:可选。塑造输出文件夹布局,无需。
    • 文件名中的空格:这让我头疼-文件从未被复制。删除空格可以解决这个问题。还没有研究过转义字符。

    我还学到了一个技巧:不要忘记在每个测试中添加这个属性。文件复制了测试运行中的第一个属性化测试,但在测试顺序更改和非属性化测试试图首先找到文件时,文件仍然丢失。


    对于那些喜欢避免部署混乱并采用@martin peck(接受答案)建议的方法的用户,可以使用以下代码访问嵌入资源的内容:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    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线程


    试试这个VS2010。因此,您不需要为每个tif添加deployitems删除

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

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

    称之为TDD

    TestMenu>Edit Testsettings下选择TDD

    单击部署。启用它,然后添加所需的文件和目录。将有一个与解决方案相关的路径。文件将被放上。例如,原始文件如下:

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

    当我运行单元测试时,它会被复制到

    1
    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中,我从以下位置调用它:

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

    不需要选择"始终复制";将文件放入测试项目;在测试代码中添加硬编码路径。对我来说,这个解决方案效果最好。我试着表达我的歉意,总是照搬,但我不喜欢。


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

    因此,当我单独运行我的测试时,它们会通过,但当同时运行它们时,第二个和随后的测试将失败,并出现"找不到文件"错误(我最初错误诊断为DeploymentItem属性不起作用)。

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


    因为我总是发现deploymentem属性一团糟,所以我使用构建后脚本来部署这些文件。-确保要复制的文件设置了"始终复制"属性。-修改测试项目生成后脚本,将文件从生成目标文件夹(bindebug)复制到测试预期的位置。


    我们在部署项问题上花费了大量时间来解决本地UnitTest运行和TeamCity UnitTest Reun中的问题。这不容易。

    很好的调试工具是ProcessExplorer。使用Process Explorer,可以检查Visual Studio在何处搜索部署项,并对项目进行更正。只需过滤路径中包含DeploymentItem文件名的所有文件操作,就可以看到它。


    除了需要检查的部署属性外,我还发现了关于deploymentem属性的其他一些内容。

    1
    2
    3
    4
    5
    6
    [TestMethod()]
    [DeploymentItem("folder\subfolder\deploymentFile.txt")]
    public void TestMethod1()
    {
       ...
    }

    deploymentfile.txt需要相对于解决方案文件,而不是testfile.cs。

    enter image description here


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

    我基本上有[deploymentem(@"foo",@"foo")]并期望它部署我的fooar。我特意把它改成[部署(@"fooar",@"fooar")]现在它就像一个魅力。


    不要使用DeploymentItem

    很难正确设置,它既没有与我的Resharper测试运行程序一起工作,也没有与Visual Studio 2017中用于MSTEST的本机运行程序一起工作。

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

    现在在你的测试中,做这个。目录只是文件相对于测试项目的目录。容易的。

    1
    2
    3
    4
    5
    6
    7
    8
        [TestMethod()]
        public void ParseProductsTest()
        {
            // Arrange
            var file = @"Features\Products\Files\Workbook_2017.xlsx";
            var fileStream = File.Open(file, FileMode.Open);
            // etc.
        }

    警告。我不知道这是否适用于自动化构建和测试系统。我还没到。


    我也面临着类似的问题。我有上面提到的所有步骤,但仍然没有运气。我正在使用VS2010。然后我发现选择了$menu>test>select active test setting>trace and test impact。在我将跟踪和测试影响更改为本地之后,它开始工作。这个页面包含了非常丰富的关于将文件复制到测试结果文件夹的信息,我觉得也要添加这个体验。