Search code examples
continuous-integrationnunitteamcitynunit-console

Different nunit versions per branch in teamcity


When teamcity NUnit 3 build step is used it asks for a path to the nunit console runner. It is configured to search for it in a specific folder in the packages, like packages\NUnit.ConsoleRunner.3.6.1\tools.

But after upgrading nunit to a newer version (3.7.0) this path needs to be changed, but it is located in build step. Is there a way to set parameter value based on branch name or how to resolve this issue of multiple nunit versions needed?


Solution

  • This is a great question. Yes, this can be done; here's one way:

    Setting TeamCity parameters dynamically based on branch

    First, create a new parameter in TeamCity:

    Add New Parameter


    Next, open a PowerShell IDE and create a simple script to modify a TeamCity parameter like this:

    PowerShell script

    Code:

    Write-Host "##teamcity[setParameter name='MyNewParameter' value='someValue']"
    

    Save this script in your source tree (as, say, SetTeamCityParameters.ps1), modifying the parameter value as required depending on the branch. For example, you could do something like this:

    Write-Host "##teamcity[setParameter name='NUnitVersion' value='3.7']"
    

    Finally, create a PowerShell build step (as the first build step in your TeamCity configuration) and include the following code in the 'Script source' (modifying the path according to where in the source tree you have saved your script):

    If (Test-Path "Source/SetTeamCityParameters.ps1") { invoke-expression "Source/SetTeamCityParameters.ps1" }
    

    Your TeamCity build will now have the correct value for this parameter based on the branch being built.


    Running a different NUnit version in TeamCity based on branch

    However, just changing a parameter might not be enough to do what you need since as far as I know you can't change that property of an NUnit build step dynamically. Fortunately, there is a workaround: create two TeamCity NUnit build steps (one cloned from the other), where the only difference is the NUnit version being targeted, something like this:

    Same build step, different NUnit versions

    Note that the two build steps are identical apart from the NUnit version being targeted and the test assembly paths, which use parameters. (In this example they use several parameters but your case is probably simpler.)

    Now you'll need to create two parameters in TeamCity, called something like TestsNUnitv2 and `TestsNUnitv3', then modify your PowerShell script to set both of them:

    Write-Host "##teamcity[setParameter name='TestsNUnitv2' value='RealTests.dll']"
    Write-Host "##teamcity[setParameter name='TestsNUnitv3' value='DummyTests.dll']"
    

    Note that here we're pointing the NUnit v2 test runner to the real test assembly and the NUnit v3 test runner to a dummy test assembly. You'll need to create this test assembly yourself and include it in your solution (on all branches) - just have one trivially passing test in it.

    Finally, modify the two build steps so that the 'v2' build step uses the 'TestsNUnitv2' path to find its test assembly and the 'v3' build step uses the other parameter.

    Any branches with the above script will run the real tests (on NUnit v2) and 'pass' the dummy test assembly (on NUnit v3). If on a particular branch you want to target NUnit v3 then simply switch the parameter values in the script on that branch only. TeamCity will set the parameters dynamically and hey presto, your tests are now running against NUnit v3.

    Let me know if anything's unclear and I'll try to explain better. Hope this helps, and sorry I'm a year late!