Wednesday, January 2, 2013

Running MSTest UnitTests using MSBuild

Since there is no target to run MSTest for MSBuild you have to do some work at your own to get this working.
So first i did some basic setup:
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
<PropertyGroup>
<!-- Path to the MSTest.exe -->
<MsTestExePath>C:\Program Files (x86)\Microsoft Visual Studio 10.0\Common7\IDE\mstest.exe</MsTestExePath>
<!-- Path to the Configfile for MSTest -->
<MsTestConfigPath>$(MSBuildProjectDirectory)\MSBuildLocalTestRun.testrunconfig</MsTestConfigPath>    
<!-- This is the Path where MSBuild will copy the compiled output -->
<OutputPath>$(MSBuildProjectDirectory)\Output</OutputPath>
<!-- The File for the Testresults -->
<MsTestResultPath>$(OutputPath)\MyResults.trx</MsTestResultPath>
</PropertyGroup>

<!-- This holds the Path to all the Dlls that contain the Unit Tests. They all end with .Test.dll.
This convention will make your live much easier.  The \**\ tells MSBuild to search recursive through the directory and subdirectories.-->
<ItemGroup>    
   <TestAssemblies Include="$(OutputPath)\**\*.Test.dll"/>
</ItemGroup>

And here is the target to run the Test:
1
2
3
4
5
6
7
8
9
<Target Name="Test">
   <RemoveDir Directories="TestResults" Condition="Exists('TestResults')" />
   <MakeDir Directories="TestResults"/>
   <PropertyGroup>
       <MsTestCommand>"$(MsTestExePath)" @(TestAssemblies->'/testcontainer:"%(FullPath)"', ' ') /resultsfile:"TestResults\Results.trx" /runconfig:"$(MsTestConfigPath)""</MsTestCommand>
    </PropertyGroup>

   <Exec Command="$(MsTestCommand)" ContinueOnError="true" />
</Target> 

The @(TestAssemblies->'/testcontainer:"%(FullPath) part transforms all the items from TestAssemblies into a single string with the string /testcontainer in front of each item. The ‘ ‘ right before the closing bracket will separate each item with a blank.

If you want to run MSTest with each Dll separately you can use a feature from MSBuild called Batching:
1
<Exec Command='"$(MsTestExePath)" /testcontainer:"%(TestAssemblies.FullPath)" /runconfig:"$(MsTestConfigPath)"' />

The tricky part is escaping the Command right so that everything is still running even if you have spaces in the directory names. I didn’t gave the name of the resultfile here because MSTest throws an error when it starts an the resultfile already exists. So i just let MSTest handle the naming of the resultfile.

More infos on MSBuild Batching can be found here.
A good Book wich covers MSBuild is this one from MS Press.

1 comment: