如何让Team Build运行MbUnit测试?

时间:2023-01-14 12:13:46

I am having trouble getting Team Build to execute my MbUnit unit tests. I have tried to edit TFSBuild.proj and added the following parts:

我无法让Team Build执行我的MbUnit单元测试。我试过编辑TFSBuild.proj并添加了以下部分:

<Project ...>
  <UsingTask TaskName="MbUnit.MSBuild.Tasks.MbUnit" AssemblyFile="path_to_MbUnit.MSBuild.Tasks.dll" />
  ...
  ...
  <ItemGroup>
    <TestAssemblies Include="$(OutDir)\Project1.dll" />
    <TestAssemblies Include="$(OutDir)\Project2.dll" />
  </ItemGroup>
  <Target Name="Tests">
    <MbUnit
      Assemblies="@(TestAssemblies)"
      ReportTypes="html"
      ReportFileNameFormat="buildreport{0}{1}"
      ReportOutputDirectory="." />
  </Target>
  ...
</Project>

But I have yet to get the tests to run.

但我还没有让测试运行。

3 个解决方案

#1


1  

Above suggestion didn't help me a lot, but I found some documentation for Team Build and adjusted my build script to override the AfterCompile target:

上面的建议对我没什么帮助,但我找到了Team Build的一些文档,并调整了我的构建脚本来覆盖AfterCompile目标:

(EDIT: Now that I have a better understanding of Team Build, I have added some more to the test runner. It will now update the Build Explorer/Build monitor with build steps with details about the test run)

(编辑:现在我已经更好地理解了Team Build,我已经向测试运行器添加了更多内容。现在它将使用构建步骤更新Build Explorer / Build监视器,其中包含有关测试运行的详细信息)

<Project ...>
  <UsingTask TaskName="MbUnit.MSBuild.Tasks.MbUnit" AssemblyFile="path_to_MbUnit.MSBuild.Tasks.dll" />
  ...
  ...
  <Target Name="AfterCompile">
    <ItemGroup>
      <TestAssemblies Include="$(OutDir)\Project1.dll" />
      <TestAssemblies Include="$(OutDir)\Project2.dll" />
    </ItemGroup>

    <BuildStep
      TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
      BuildUri="$(BuildUri)"
      Message="Running tests (cross your fingers)...">
      <Output TaskParameter="Id" PropertyName="StepId" />
    </BuildStep>

    <MbUnit
      Assemblies="@(TestAssemblies)"
      ReportTypes="html"
      ReportFileNameFormat="buildreport{0}{1}"
      ReportOutputDirectory="." />

    <BuildStep
      TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
      BuildUri="$(BuildUri)"
      Id="$(StepId)"
      Message="Yay! All tests succeded!"
      Status="Succeeded" />
    <OnError ExecuteTargets="MarkBuildStepAsFailed" />
  </Target>

  <Target Name="MarkBuildStepAsFailed">
    <BuildStep
      TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
      BuildUri="$(BuildUri)"
      Id="$(StepId)"
      Message="Oh no! Some tests have failed. See test report in drop folder for details."
      Status="Failed" />
  </Target>
  ...
</Project>

#2


1  

You don't need to call MSBuild again to have your ItemGroup populated, there is a easier way. Re-calling MSBuild has its downsides, like passing all Teambuild-parameters on to make TeamBuild-tasks work. We use the CreateItem task from MSBuild to dynamically generate a ItemGroup with all our Test DLLs:

您不需要再次调用MSBuild来填充您的ItemGroup,这是一种更简单的方法。重新调用MSBuild有其缺点,例如传递所有Teambuild参数以使TeamBuild-tasks工作。我们使用MSBuild中的CreateItem任务动态生成包含所有Test DLL的ItemGroup:

<Target Name="AfterCompile">
<CreateItem Include="$(OutDir)\*.Test.dll">
           <Output
               TaskParameter="Include"
               ItemName="TestBinaries"/>
</CreateItem>
</Target><!--Test run happens in a later target in our case, we use MSTest -->

#3


0  

The way ItemGroups in MSBuild work is that they are evaluated at the very start of the MSBuild scripts, before any targets are ran. Therefore if the assemblies don't exist yet (which they will not because they have not been built yet) then the ItemGroups will not find any files.

MSBuild中ItemGroups的工作方式是在运行任何目标之前,在MSBuild脚本的最开始对它们进行评估。因此,如果程序集尚不存在(它们不会因为它们尚未构建而存在),那么ItemGroups将找不到任何文件。

The usual pattern in MSBuild to work around this is to re-call MSBuild again at this point so that when the item groups get evaluated in the inner MSBuild execution, the assemblies will exist.

MSBuild中解决此问题的常用模式是此时再次重新调用MSBuild,以便在内部MSBuild执行中评估项目组时,程序集将存在。

For example, something like:

例如,类似于:

  <PropertyGroup>
    <TestDependsOn>
      $(TestDependsOn);
      CallMbUnitTests;
    </TestDependsOn>
  </PropertyGroup>

  <Target Name="CallMbUnitTests">
    <MSBuild Projects="$(MSBuildProjectFile)"
             Properties="BuildAgentName=$(BuildAgentName);BuildAgentUri=$(BuildAgentUri);BuildDefinitionName=$(BuildDefinitionName);BuildDefinitionUri=$(BuildDefinitionUri);
                         BuildDirectory=$(BuildDirectory);BuildNumber=$(BuildNumber);CompilationStatus=$(CompilationStatus);CompilationSuccess=$(CompilationSuccess);
                         ConfigurationFolderUri=$(ConfigurationFolderUri);DropLocation=$(DropLocation);
                         FullLabelName=$(FullLabelName);LastChangedBy=$(LastChangedBy);LastChangedOn=$(LastChangedOn);LogLocation=$(LogLocation);
                         MachineName=$(MachineName);MaxProcesses=$(MaxProcesses);Port=$(Port);Quality=$(Quality);Reason=$(Reason);RequestedBy=$(RequestedBy);RequestedFor=$(RequestedFor);
                         SourceGetVersion=$(SourceGetVersion);StartTime=$(StartTime);Status=$(Status);TeamProject=$(TeamProject);TestStatus=$(TestStatus);
                         TestSuccess=$(TestSuccess);WorkspaceName=$(WorkspaceName);WorkspaceOwner=$(WorkspaceOwner);
                         SolutionRoot=$(SolutionRoot);BinariesRoot=$(BinariesRoot);TestResultsRoot=$(TestResultsRoot)"
             Targets="RunMbUnitTests"/>
  </Target>

  <ItemGroup>
    <TestAssemblies Include="$(OutDir)\Project1.dll" />
    <TestAssemblies Include="$(OutDir)\Project2.dll" />
  </ItemGroup>
  <Target Name="RunMbUnitTests">
    <MbUnit
      Assemblies="@(TestAssemblies)"
      ReportTypes="html"
      ReportFileNameFormat="buildreport{0}{1}"
      ReportOutputDirectory="." />
  </Target>

Hope that helps, good luck.

希望有所帮助,祝你好运。

Martin.

#1


1  

Above suggestion didn't help me a lot, but I found some documentation for Team Build and adjusted my build script to override the AfterCompile target:

上面的建议对我没什么帮助,但我找到了Team Build的一些文档,并调整了我的构建脚本来覆盖AfterCompile目标:

(EDIT: Now that I have a better understanding of Team Build, I have added some more to the test runner. It will now update the Build Explorer/Build monitor with build steps with details about the test run)

(编辑:现在我已经更好地理解了Team Build,我已经向测试运行器添加了更多内容。现在它将使用构建步骤更新Build Explorer / Build监视器,其中包含有关测试运行的详细信息)

<Project ...>
  <UsingTask TaskName="MbUnit.MSBuild.Tasks.MbUnit" AssemblyFile="path_to_MbUnit.MSBuild.Tasks.dll" />
  ...
  ...
  <Target Name="AfterCompile">
    <ItemGroup>
      <TestAssemblies Include="$(OutDir)\Project1.dll" />
      <TestAssemblies Include="$(OutDir)\Project2.dll" />
    </ItemGroup>

    <BuildStep
      TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
      BuildUri="$(BuildUri)"
      Message="Running tests (cross your fingers)...">
      <Output TaskParameter="Id" PropertyName="StepId" />
    </BuildStep>

    <MbUnit
      Assemblies="@(TestAssemblies)"
      ReportTypes="html"
      ReportFileNameFormat="buildreport{0}{1}"
      ReportOutputDirectory="." />

    <BuildStep
      TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
      BuildUri="$(BuildUri)"
      Id="$(StepId)"
      Message="Yay! All tests succeded!"
      Status="Succeeded" />
    <OnError ExecuteTargets="MarkBuildStepAsFailed" />
  </Target>

  <Target Name="MarkBuildStepAsFailed">
    <BuildStep
      TeamFoundationServerUrl="$(TeamFoundationServerUrl)"
      BuildUri="$(BuildUri)"
      Id="$(StepId)"
      Message="Oh no! Some tests have failed. See test report in drop folder for details."
      Status="Failed" />
  </Target>
  ...
</Project>

#2


1  

You don't need to call MSBuild again to have your ItemGroup populated, there is a easier way. Re-calling MSBuild has its downsides, like passing all Teambuild-parameters on to make TeamBuild-tasks work. We use the CreateItem task from MSBuild to dynamically generate a ItemGroup with all our Test DLLs:

您不需要再次调用MSBuild来填充您的ItemGroup,这是一种更简单的方法。重新调用MSBuild有其缺点,例如传递所有Teambuild参数以使TeamBuild-tasks工作。我们使用MSBuild中的CreateItem任务动态生成包含所有Test DLL的ItemGroup:

<Target Name="AfterCompile">
<CreateItem Include="$(OutDir)\*.Test.dll">
           <Output
               TaskParameter="Include"
               ItemName="TestBinaries"/>
</CreateItem>
</Target><!--Test run happens in a later target in our case, we use MSTest -->

#3


0  

The way ItemGroups in MSBuild work is that they are evaluated at the very start of the MSBuild scripts, before any targets are ran. Therefore if the assemblies don't exist yet (which they will not because they have not been built yet) then the ItemGroups will not find any files.

MSBuild中ItemGroups的工作方式是在运行任何目标之前,在MSBuild脚本的最开始对它们进行评估。因此,如果程序集尚不存在(它们不会因为它们尚未构建而存在),那么ItemGroups将找不到任何文件。

The usual pattern in MSBuild to work around this is to re-call MSBuild again at this point so that when the item groups get evaluated in the inner MSBuild execution, the assemblies will exist.

MSBuild中解决此问题的常用模式是此时再次重新调用MSBuild,以便在内部MSBuild执行中评估项目组时,程序集将存在。

For example, something like:

例如,类似于:

  <PropertyGroup>
    <TestDependsOn>
      $(TestDependsOn);
      CallMbUnitTests;
    </TestDependsOn>
  </PropertyGroup>

  <Target Name="CallMbUnitTests">
    <MSBuild Projects="$(MSBuildProjectFile)"
             Properties="BuildAgentName=$(BuildAgentName);BuildAgentUri=$(BuildAgentUri);BuildDefinitionName=$(BuildDefinitionName);BuildDefinitionUri=$(BuildDefinitionUri);
                         BuildDirectory=$(BuildDirectory);BuildNumber=$(BuildNumber);CompilationStatus=$(CompilationStatus);CompilationSuccess=$(CompilationSuccess);
                         ConfigurationFolderUri=$(ConfigurationFolderUri);DropLocation=$(DropLocation);
                         FullLabelName=$(FullLabelName);LastChangedBy=$(LastChangedBy);LastChangedOn=$(LastChangedOn);LogLocation=$(LogLocation);
                         MachineName=$(MachineName);MaxProcesses=$(MaxProcesses);Port=$(Port);Quality=$(Quality);Reason=$(Reason);RequestedBy=$(RequestedBy);RequestedFor=$(RequestedFor);
                         SourceGetVersion=$(SourceGetVersion);StartTime=$(StartTime);Status=$(Status);TeamProject=$(TeamProject);TestStatus=$(TestStatus);
                         TestSuccess=$(TestSuccess);WorkspaceName=$(WorkspaceName);WorkspaceOwner=$(WorkspaceOwner);
                         SolutionRoot=$(SolutionRoot);BinariesRoot=$(BinariesRoot);TestResultsRoot=$(TestResultsRoot)"
             Targets="RunMbUnitTests"/>
  </Target>

  <ItemGroup>
    <TestAssemblies Include="$(OutDir)\Project1.dll" />
    <TestAssemblies Include="$(OutDir)\Project2.dll" />
  </ItemGroup>
  <Target Name="RunMbUnitTests">
    <MbUnit
      Assemblies="@(TestAssemblies)"
      ReportTypes="html"
      ReportFileNameFormat="buildreport{0}{1}"
      ReportOutputDirectory="." />
  </Target>

Hope that helps, good luck.

希望有所帮助,祝你好运。

Martin.