I have migrated my MBUnit tests to NUnit, considering MBUnit has been “on hiatus” for about a year now. NUnit is not much more agile, but at least there is a semblance of life on their Github account.
The switch has been surprisingly easy: change the namespace, change TestRow with Test, and change Row with TestCase. Easy!
Run unit tests in your continuous integration platform
In order to integrate the tests in our continuous integration platform, while minimizing build time, I have split the setup package build and the unit tests run. So I have a job that runs at each commit, that builds the project and generates the setup packages; and another job running at midnight, that only builds the project and runs unit tests.
Apparently, using the automatic package restore from Visual Studio is now obsolete with the latest Nuget versions. So I followed the instructions and migrated to Nuget package restore. Remember to download nuget.exe from nuget.org, add it to the CI server’s PATH, and restart Jenkins.
Add the NUnit Nuget packages to the test projects, and remember to add the NUnit Runner Nuget package to the solution! It will be much easier to run the unit tests this way (no need to install NUnit on the CI server).
I’m using PSAke for my build process (awesome tool!), so now my script looks like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
Properties { $ROOT_PATH = [System.IO.Path]::GetFullPath((Join-Path (pwd) ".\build")) $APP_PATH = Join-Path $ROOT_PATH "app" $TESTS_PATH = Join-Path $ROOT_PATH "tests" $NUNIT_PATH = Join-Path (pwd) "packages\NUnit.Runners.2.6.3\tools\nunit-console-x86.exe" # note that if you build your test binaries for x86, you must use the x86 test runner } Framework "4.0x86" # this builds using the 32-bit .Net 4 # This is the task that is run by the "standard" job task default -depends Cleanup, Build, Config, Setup # this is the task that is run by the "tests" job task Test -depends Cleanup, BuildNUnit { Get-ChildItem $TESTS_PATH -Filter "*.*Test*.dll" | % { $result = (Join-Path $resultsPath $_.Name) -replace ".dll",".xml" Start-Process $NUNIT_PATH -ArgumentList "`"$($_.FullName)`" /framework:net-4.0 /nologo /result:`"$result`"" -Wait -NoNewWindow } } task Restore { & nuget restore } task Cleanup { # remove all binaries - only useful for local run } task Build -depends Restore { Exec { msbuild "mysolution.sln" /t:Build /p:Configuration=Release /p:Platform=x86 } } task BuildNUnit -depends Restore { Exec { msbuild "mysolution.sln" /t:Build /p:Configuration=NUnit /p:Platform=x86 } } task Config { # modify config values } task Setup { # run InnoSetup to generate setup packages } |
And now my Jenkins jobs consist of a simple batch line:
1 |
powershell "Import-Module .\psake.psm1 ; Invoke-Psake .\build.ps1 MYTASKNAME" |
I have sumbled on a System.BadImageFormatException while running tests in Jenkins using nunit-console, or trying to add the assemblies to the NUnit GUI runner. Here are a few things to remember:
Do not use AnyCPU
Your test assemblies, assemblies linked by your tests, and really your whole project, should be built in 32-bits mode, so that they can be run by the 32-bits test runner. Personnaly, I created a “NUnit” solution configuration just for this. It allows me to select which assemblies are built in which case: no need to build tests in the general build, and no need to build stuff like bootstrapper exes in the test build.
Check your build paths
If you create a new configuration like I did, remember to change the build path! My main project builds in the \build\app folder, and my tests are located in \build\tests. I spent a few minutes wondering why the platform change did nothing, before finding out that my x86 test assemblies were in bin\x86\NUnit (the default value).
Check the framework version
Select the proper .Net framework with the /framework:net-4.0 switch. NUnit should be able to find out automagically, but sometimes it doesn’t.