2008-12-12 56 views
6

我想获得我的项目根目录下的所有单元测试程序集列表。我能做到这一点,如下所示:标准化MSBuild中的项目列表

<CreateItem Include="**\bin\**\*.UnitTest.*.dll"> 
    <Output TaskParameter="Include" ItemName="Items"/> 
</CreateItem> 

然而,由于它们在多个子目录中存在这样会发现同样的DLL多次。是否有一种简单的方法让我根据项目元数据进行规范化(即文件名和扩展名),以便获得唯一单元测试DLL的列表?还是我必须诉诸写我自己的任务?

回答

4

MSBuild Extension Pack的包含任务MSBuildHelper,支持命令RemoveDuplicateFiles

<CreateItem Include="**\bin\**\*.UnitTest.*.dll"> 
    <Output TaskParameter="Include" ItemName="Items"/> 
</CreateItem> 
<MSBuild.ExtensionPack.Framework.MsBuildHelper TaskAction="RemoveDuplicateFiles" InputItems1="@(Items)"> 
    <Output TaskParameter="OutputItems" ItemName="Items"/> 
</MSBuild.ExtensionPack.Framework.MsBuildHelper> 
+0

听起来很有用 - 谢谢。下次尝试这个时候我需要它。 – 2009-08-24 09:17:35

2

我在网上有一个很好的搜索,找不到任何这样做的方式。如果有人知道一个干净的内置方式,请让我知道。同时,我写了一个简单的任务来完成这项工作。用法是这样的:

<NormalizeByMetadata Items="@(ItemsToNormalize)" MetadataName="Filename"> 
    <Output TaskParameter="NormalizedItems" ItemName="MyNormalizedItems"/> 
</NormalizeByMetadata> 

上述任务已执行后,MyNormalizedItems只会包含ItemsToNormalize具备为Filename元数据的独特价值的项目。如果两个或更多项目的元数据具有相同的值,则第一个匹配项将包含在输出中。

用于MSBuild任务的代码是:

public class NormalizeByMetadata : Task 
{ 
    [Required] 
    public ITaskItem[] Items 
    { 
     get; 
     set; 
    } 

    [Required] 
    public string MetadataName 
    { 
     get; 
     set; 
    } 

    [Output] 
    public ITaskItem[] NormalizedItems 
    { 
     get; 
     private set; 
    } 

    public override bool Execute() 
    { 
     NormalizedItems = Items.Distinct(new ItemEqualityComparer(MetadataName)).ToArray(); 
     return true; 
    } 

    private sealed class ItemEqualityComparer : IEqualityComparer<ITaskItem> 
    { 
     private readonly string _metadataName; 

     public ItemEqualityComparer(string metadataName) 
     { 
      Debug.Assert(metadataName != null); 
      _metadataName = metadataName; 
     } 

     public bool Equals(ITaskItem x, ITaskItem y) 
     { 
      if (x == null || y == null) 
      { 
       return x == y; 
      } 

      var xMetadata = x.GetMetadata(_metadataName); 
      var yMetadata = y.GetMetadata(_metadataName); 
      return string.Equals(xMetadata, yMetadata); 
     } 

     public int GetHashCode(ITaskItem obj) 
     { 
      if (obj == null) 
      { 
       return 0; 
      } 

      var objMetadata = obj.GetMetadata(_metadataName); 
      return objMetadata.GetHashCode(); 
     } 
    } 
} 
+0

如何为NormalizeByMetadata任务创建单元测试? – Kiquenet 2014-09-11 08:15:10

4

即使这是老了,我永远无法得到解决托马斯的工作,不过我的确发现仅使用内置命令用的MSBuild 4.0版解决方法的排序:

<ItemGroup> 
    <TestAssemblies Include="$(SolutionRoot)\**\bin\*.Tests.dll" /> 
    <TestItems Include="%(TestAssemblies.FileName)%(TestAssemblies.Extension)"> 
     <ItemPath>%(TestAssemblies.Identity)</ItemPath> 
    </TestItems> 
    <DistinctTestItems Include="@(TestItems->Distinct())"></DistinctTestItems> 
</ItemGroup> 
<Message Text="%(DistinctTestItems.ItemPath)" Importance="high" />