MSBuild Community Tasks NUnit and Mono

As an experiment, I modified an NUnit test project to automatically test itself after the build process. This way, the unit tests become an integral part of the build; just by building in Visual Studio you'll know if you've broken a unit test.

I used the NUnit task from the MSBuild Community Tasks project. It worked fine on Windows and Visual Studio. Then, I tried to build also in Linux with Mono and as usual there were a few differences. However, it was quite easy to fix.

First of all, file name capitalizations. Linux is case sensitive about filenames so make sure the MSBuild.Community.Tasks.targets file is imported in the csproj file using in the correct case. In my case, I had to change a “Targets” to “targets”.

Then, that targets file complained, something about not being able to resolve $([MSBUILD]::Unescape($(MSBuildCommunityTasksPath). That expression is on the top of the file and it looks a bit complicated for what it is supposed to be doing. Grabbing some inspiration from NuGet.targets, I created two versions of that PropertyGroup: one for Windows, which I left intact because I didn't want to change whatever it's doing, and one new one for “Non-Windows”, which I made it look a bit simpler.

So from this:

<PropertyGroup>
  <MSBuildCommunityTasksPath Condition="'$(MSBuildCommunityTasksPath)' == ''">$(MSBuildExtensionsPath)MSBuildCommunityTasks</MSBuildCommunityTasksPath>
    <MSBuildCommunityTasksLib>$([MSBUILD]::Unescape($(MSBuildCommunityTasksPath)MSBuild.Community.Tasks.dll))</MSBuildCommunityTasksLib>
</PropertyGroup>

I went to this:

<PropertyGroup>
    <MSBuildCommunityTasksPath Condition="'$(MSBuildCommunityTasksPath)' == ''">$(MSBuildExtensionsPath)MSBuildCommunityTasks</MSBuildCommunityTasksPath>
</PropertyGroup>

<PropertyGroup Condition=" '$(OS)' == 'Windows_NT'">
    <MSBuildCommunityTasksLib>$([MSBUILD]::Unescape($(MSBuildCommunityTasksPath)MSBuild.Community.Tasks.dll))</MSBuildCommunityTasksLib>
</PropertyGroup>

<PropertyGroup Condition=" '$(OS)' != 'Windows_NT'">
    <MSBuildCommunityTasksLib>$(MSBuildCommunityTasksPath)MSBuild.Community.Tasks.dll</MSBuildCommunityTasksLib>
</PropertyGroup>

The next change is about locating NUnit itself. The NUnit executable will be searched by default somewhere under C:Program Files, which apparently isn't going to work in Linux. Again, with the same approach, we define a property named NUnitToolPath that holds the NUnit path per platform:

<PropertyGroup Condition=" '$(OS)' == 'Windows_NT'">
    <NUnitToolPath>C:Program FilesNUnit 2.6.2bin</NUnitToolPath>
</PropertyGroup>

<PropertyGroup Condition=" '$(OS)' != 'Windows_NT'">
    <NUnitToolPath>/usr/local/bin</NUnitToolPath>
</PropertyGroup>

So for Windows it will look for the executable nunit-console in the first path and for Linux it will use the path /usr/local/bin (that's where my mono installation lives).

One final part has to do with nunit-console itself. In my mono installation, that executable was using the .NET 2.0 version of nunit, which couldn't load my .NET 4.0 unit tests. Since I don't have any .NET 2.0 projects hanging around, I couldn't care less about .NET 2.0 so the solution here was to convert nunit-console into a symbolic link pointing to nunit-console4. Mission accomplished!

What if I had some projects needing .NET 2.0? The nunit-console executable name is hard-coded inside the NUnit task, but MSBuild Community Tasks is open source so I guess one could go about making that value also configurable.

You can have a look at the entire thing at github. Just for the fun of it the other day I started a project creating a GWBasic compiler in C#. There's a test project over there that shows how to use the NUnit task and there's also the modified version of the MSBuild.Community.Tasks.targets.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s