msbuild + typemock + xunit.net configuration

0 votes

We recently switched from gallio to xunit.net. I need to convert our msbuild scripts to work with the new configuration. What I have is not working:

	<Target Name="TypeMock">
		<Message Text="Using XUnit from $(XUnitBase)..." />
		<Message Text="Using TypeMock from $(TypeMockBase)..." />
		<CallTarget Targets="CreateReportDirectory" />
		<CallTarget Targets="RegisterTypeMock" Condition="$(IsBuildServer)" />
		<TypeMockStart/>
		<xunit Assemblies="@(MockTestAssembly)"
			WorkingFolder="$(CCNetWorkingDirectory)"
			Html="$(ReportDirectory)\TypeMock.TestReport.html"
			Verbose="$(Verbose)"
			Xml="$(ReportDirectory)\TypeMock.TestReport.xml">
			<Output TaskParameter="ExitCode" PropertyName="ExitCode"/>
		</xunit>
		<TypeMockStop/>
		<Error Text="Mock test execution failed" Condition="'$(ExitCode)' != 0" />
	</Target>

Using this configuration, Typemock tests throw the familiar "Typemock Isolator is currently disabled" exception when isolated/mocked tests are encountered. I've tried adding xunit.runner.msbuild.dll to my namespaces.dat, but that didn't seem to help.

We are using msbuild 12.0, xunit.net 1.9.2, and typemock 7.5.6.1.

Any assistance to get this working would be greatly appreciated.

asked Feb 7, 2015 by lanceheld (230 points)

2 Answers

0 votes
 
Best answer

Inga, I came to the same conclusion yesterday. My final solution was to use the TypeMockRegister, Start, and Stop tasks in conjunction with the exec task out to xunit. My common target file looks like this (see the RunXUnitConsole task):

<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
	<PropertyGroup>
		<Flavor Condition="'$(Flavor)'==''">DebugFull</Flavor>
		<CCNetWorkingDirectory Condition="'$(CCNetWorkingDirectory)'==''">$(MsBuildProjectDirectory)</CCNetWorkingDirectory>
		<ReportDirectory Condition="'$(ReportDirectory)'==''">$(CCNetWorkingDirectory)\BuildResults</ReportDirectory>
		<Verbose Condition="'$(Verbose)'==''">false</Verbose>
		<XUnitBase Condition="'$(XUnitBase)'==''">$(MSBuildThisFileDirectory)\..\..\External\NuGetPackages\xunit.runners.1.9.2\tools</XUnitBase>
		<XUnitTasks>$(XUnitBase)\xunit.runner.msbuild.dll</XUnitTasks>
		<XUnitConsole>$(XUnitBase)\xunit.console.clr4.x86.exe</XUnitConsole>
		<XUnitConsoleConfig>$(MSBuildThisFileDirectory)\xunit.console.clr4.x86.exe.config</XUnitConsoleConfig>
		<TypeMockBase Condition="'$(TypeMockBase)'==''">$(MSBuildThisFileDirectory)\..\..\External\NuGetPackages\TypeMock.7.5.6.1\lib\net40</TypeMockBase>
		<TypeMockTasks>$(TypeMockBase)\TypeMock.MSBuild.dll</TypeMockTasks>
		<UseTypeMock Condition="'$(UseTypeMock)'==''">false</UseTypeMock>
		<IsBuildServer>$(COMPUTERNAME.StartsWith('CISERVER', System.StringComparison.OrdinalIgnoreCase))</IsBuildServer>
		<XmlReport>XUnit.TestReport.xml</XmlReport>
	</PropertyGroup>

	<ItemGroup>
		<ReportFiles Include="$(ReportDirectory)\*.*" />
	</ItemGroup>
	
	<UsingTask TaskName="Xunit.Runner.MSBuild.xunit" AssemblyFile="$(XUnitTasks)" />
	<UsingTask TaskName="TypeMock.MSBuild.TypeMockRegister" AssemblyFile="$(TypeMockTasks)" />
	<UsingTask TaskName="TypeMock.MSBuild.TypeMockStart" AssemblyFile="$(TypeMockTasks)" />
	<UsingTask TaskName="TypeMock.MSBuild.TypeMockStop" AssemblyFile="$(TypeMockTasks)" />
	
	<Target Name="RunXUnitTask">
		<Message Text="Using XUnit from $(XUnitBase)..." />
		<CallTarget Targets="CreateReportDirectory" />
		<CallTarget Targets="StartTypeMock" Condition="$(UseTypeMock)" />
		<xunit Assemblies = "@(TestAssembly)"
			WorkingFolder="$(CCNetWorkingDirectory)"
			Verbose="$(Verbose)"
			Xml="$(ReportDirectory)\$(XmlReport)">
			<Output TaskParameter="ExitCode" PropertyName="ExitCode"/>
		</xunit>
		<CallTarget Targets="StopTypeMock" Condition="$(UseTypeMock)" />
		<Error Text="Test execution failed" Condition="'$(ExitCode)' != 0" />
	</Target>

	<Target Name="RunXUnitConsole">
		<Message Text="Using XUnit from $(XUnitBase)..." />
		<CallTarget Targets="CreateReportDirectory" />
		<CallTarget Targets="StartTypeMock" Condition="$(UseTypeMock)" />
		<CallTarget Targets="CopyXUnitConsoleConfig" />
		<Exec ContinueOnError="true" Command=""$(XUnitConsole)" "%(TestAssembly.Identity)" /xml "$(ReportDirectory)\%(TestAssembly.Filename).report.xml" /silent">
			<Output TaskParameter="ExitCode" PropertyName="ExitCode"/>
		</Exec>
		<CallTarget Targets="StopTypeMock" Condition="$(UseTypeMock)" />
		<CallTarget Targets="MergeXmlReports" />
		<Error Text="Console runner test execution failed" Condition="'$(ExitCode)' != 0" />
	</Target>

	<Target Name="RunXUnitConsoleWithConfig">
		<Message Text="Using XUnit from $(XUnitBase)..." />
		<CallTarget Targets="CreateReportDirectory" />
		<CallTarget Targets="StartTypeMock" Condition="$(UseTypeMock)" />
		<CallTarget Targets="CopyXUnitConsoleConfig" />
		<Exec ContinueOnError="true" Command=""$(XUnitConsole)" "%(XUnitConfig.Identity)" /silent">
			<Output TaskParameter="ExitCode" PropertyName="ExitCode"/>
		</Exec>
		<CallTarget Targets="StopTypeMock" Condition="$(UseTypeMock)" />
		<CallTarget Targets="MergeXmlReports" />
		<Error Text="Console runner test execution failed" Condition="'$(ExitCode)' != 0" />
	</Target>

	<Target Name="CopyXUnitConsoleConfig">
		<Copy SourceFiles="$(XUnitConsoleConfig)" DestinationFolder="$(XUnitBase)" />
	</Target>
	
	<Target Name="CreateReportDirectory">
		<MakeDir Directories="$(ReportDirectory)" Condition = "!Exists('$(ReportDirectory)')"/>
		<Delete Files="@(ReportFiles)" />
	</Target>
	
	<Target Name="StartTypeMock">
		<Message Text="Using TypeMock from $(TypeMockBase)..." />
		<CallTarget Targets="RegisterTypeMock" Condition="$(IsBuildServer)" />
		<TypeMockStart/>
	</Target>
	
	<Target Name="StopTypeMock">
		<TypeMockStop/>
	</Target>
	
	<Target Name="RegisterTypeMock">
		<TypeMockRegister Company="******" License="******" AutoDeploy="true"/>
	</Target>
	
	<Target Name="MergeXmlReports">
		<ItemGroup>
			<XmlReportFiles Include="@(TestAssembly->'$(ReportDirectory)\%(filename).report.xml')" />
		</ItemGroup>
		<Message Text="Merging reports: @(XmlReportFiles->'%(filename)%(extension)')" />
		<ItemGroup>
			<XmlReportLines Include="<assemblies>"/>
		</ItemGroup>
		<ReadLinesFromFile File="%(XmlReportFiles.Identity)">
            <Output TaskParameter="Lines" ItemName="XmlReportLines"/>
        </ReadLinesFromFile>
		<ItemGroup>
			<XmlReportLines Include="</assemblies>"/>
		</ItemGroup>
		<Message Text="Writing merged reports to: $(ReportDirectory)\$(XmlReport)" />
        <WriteLinesToFile File="$(ReportDirectory)\$(XmlReport)" Lines="@(XmlReportLines->'%(Identity)', '%0a%0d')" Overwrite="true" Encoding="Unicode" />
	</Target>
</Project>

and my solution-specific target looks like this (with the UseTypeMock property set to true):

<Project DefaultTargets="RunTests" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="12.0">
	<PropertyGroup>
		<XUnitBase>$(MsBuildProjectDirectory)\..\..\External\NuGetPackages\xunit.runners.1.9.2\tools</XUnitBase>
		<TypeMockBase>$(MsBuildProjectDirectory)\..\..\External\NuGetPackages\TypeMock.7.5.6.1\lib\net40</TypeMockBase>
		<UseTypeMock>true</UseTypeMock>
	</PropertyGroup>
	<Import Project ="..\..\Common\MSBuildTargets\Common.XUnit.targets" />
	
	<ItemGroup>
		<TestAssembly Include="testAssembly01.dll" />
		<TestAssembly Include="testAssembly02.dll" />
	</ItemGroup>
	
	<Target Name="RunTests" DependsOnTargets="RunXUnitConsole" />
</Project>

Note that the common target has the additional benefit of combining the xunit xml reports at the end (just like the xunit task behaves).

answered Feb 12, 2015 by lanceheld (230 points)
0 votes

Hi,

In order to work with xunit you need to use exec command,

From there you need to run the xunit and add our TMockRunner.exe tool .

This is a simple template: (for more information/instructions about TMockRunner.exe)


<Exec Command="TMockRunner.exe –register [company] [license key] xunit.console [MyTestLibrary.dll]"/>

 

Let me know if it helped you.

Inga Ratner Support Team
image
answered Feb 12, 2015 by inga (320 points)
...