17

NUnit 3.0 is supported by TeamCity 9.1.x now however you have to install the runner and specify the path to the nunit3.console.exe in the step. My question is where do I copy the nunit3-console.exe? Do I have to put this on all the agents? Do I put it in a directory on my main TeamCity server and it will get shared or pulled by the agents? There doesn't seem to be good documentation on where to copy these files so that all the agents can use them.

Brett Mathe
  • 6,429
  • 7
  • 23
  • 24

8 Answers8

28

You should have the NUnit console on the each agent where you would like to run NUnit tests.

The best option is:

  1. Add reference to the NuGet package (https://www.nuget.org/packages/NUnit.Runners/).

  2. To restore package you could use "NuGet Installer" build step, see following blog post: https://blog.jetbrains.com/teamcity/2013/08/nuget-package-restore-with-teamcity/

  3. After that you just set path like "packages\NUnit.Console.3.0.0\tools\nunit3-console.exe" from the restored NuGet package.

NikolayP
  • 389
  • 2
  • 5
  • 13
    Is it me or is this a bit ridiculous? I went down this path too without seeing this answer, but it strikes me that when the package will be updated in the solution, then people are going to be left wondering why their TC build fails due to the package version name no longer being up to date. – Tom Aug 04 '16 at 15:16
  • 1
    I upvoted this answer because it taught me that there was a NuGet package that contained the runner. I had been installing NUnit directly on my build agent and referencing that path, instead. However, I agree with @Tom that the hard-coded version number in the `packages` path is suboptimal; developers would have to keep the version in sync across all build configurations so that the hard-coded directory name would work. Perhaps a separate build step can be set up to detect the correct path and assign it to a variable? – NathanAldenSr Aug 09 '16 at 23:32
  • 2
    @NathanAldenSr It would be better if TC could auto-detect the latest console runner in the packages directory, without having to specify anything. It would be even better if TC could even fetch the latest version from NuGet (unless you've supplied it in your solution) and run it against that, so that devs don't need to think of their build server requiments when putting a project together. – Tom Aug 10 '16 at 13:41
  • 2
    The Nunit.Runners package is now deprecated and you have to use the NUnit.ConsoleRunner. Careful not to use one of the other 10+ nunit packages that sounds deceivingly similar, i.e., NUnit.Console, NUnit.Runners, NUnit.Engine, NUnit.Extension.TeamCityEventListener, etc., etc. Considering XUnit myself... this is getting bit tedious just to run some unit tests. – JTW Oct 14 '16 at 18:25
  • 2
    @woogy the singular Nunit.Console package will pull in the Nunit.ConsoleRunner and the other bits, though you have to give a path to Nunit.ConsoleRunner and NOT just Nunit.Console for the exe. – dragon788 Nov 15 '16 at 00:14
  • Also see samples here https://github.com/JetBrains/teamcity-nunit-samples/blob/master/restore.proj and https://github.com/JetBrains/teamcity-nunit-samples/blob/master/nunit-utils.targets – NikolayP Nov 15 '16 at 12:36
  • TeamCity team are working on implementing an alternative approach when you can select the NUnit version to use globally on all the agents (the way it is currently done for NuGet). It will resolve any inconveniences you might be experiencing at the moment. – NikolayP Nov 15 '16 at 12:37
  • @NikolayP any news on the approach described above? 2017.1? – Kralizek Mar 14 '17 at 20:39
  • 1
    As of 2017.1.3 it is possible to install packages in a directory without a version number (see my [answer](https://stackoverflow.com/a/45877204/1811525) for more details). – CodeFox Aug 25 '17 at 08:24
7

Building on @NikolayP's answer:

  1. Add reference to the NuGet package (https://www.nuget.org/packages/NUnit.Runners/).
  2. To restore package you could use "NuGet Installer" build step, see following blog post: https://blog.jetbrains.com/teamcity/2013/08/nuget-package-restore-with-teamcity/
  3. After that you just set path like "packages\NUnit.Console.3.0.0\tools\nunit3-console.exe" from the restored NuGet package.

I wrote the following PowerShell script to determine the correct NUnit.ConsoleRunner package directory and populate a TeamCity variable before the NUnit task is run. It uses the most recent version of the NUnit.Console package.

$SrcDirectory = "%src.directory%"
$PackagesDirectory = Join-Path $SrcDirectory packages

$NUnitConsoleRunnerPackageDirectory = Get-ChildItem (Join-Path $PackagesDirectory NUnit.ConsoleRunner.*) | %{
    @{
        Directory = $_.FullName
        Version = [Version]::Parse(($_.Name -replace "NUnit.ConsoleRunner.",""))
    }
} | Sort-Object Version -Descending | Select-Object -First 1 | %{ $_.Directory }

if (!$NUnitConsoleRunnerPackageDirectory) {
    throw [IO.DirectoryNotFoundException] "NUnit console runner package directory not found"
}

Write-Output "##teamcity[setParameter name='nunit.consolerunner.directory' value='$NUnitConsoleRunnerPackageDirectory']"

Note that you'll need to define the src.directory variable to point to the directory that contains the packages directory on your build agent, or otherwise supply the necessary root directory for the PowerShell script to work. You'll also need to define the nunit.consolerunner.directory variable with a default value of empty.

The script will also throw an exception if, for whatever reason, an NUnit.ConsoleRunner directory could not be found.

NathanAldenSr
  • 7,841
  • 4
  • 40
  • 51
  • Thank you for inspiring me to take this 1 step further. Typically MSBuild projects have a single solution file that you need to specify with a path in TeamCity. Using this existing variable and `Split-Path` I was able to take the information already required to be set in a project and determine the correct packages directory and return the full path to the tools/nunit3-console.exe into an Nunit3Path variable. – dragon788 Nov 15 '16 at 00:05
  • As of 2017.1.3 it is possible to install packages in a directory without a version number (see my [answer](https://stackoverflow.com/a/45877204/1811525) for more details). – CodeFox Aug 25 '17 at 08:24
5

Also you could follow this instruction: https://confluence.jetbrains.com/display/TCD9/Getting+Started+with+NUnit

NikolayP
  • 389
  • 2
  • 5
  • 1
    I used the NUnit build step for NUnit3, however TeamCity kept adding 'nunit-console.exe' to whatever value I put into the 'Path to NUnit console runner' field, despite the help saying 'Specify the path to NUnit console runner including the file name.' I eventually upgraded to TeamCity 9.1.6 and the problem seems to have been fixed. I used Nuget to get NUnit Console 3.0.1 and a path value of '%teamcity.build.checkoutDir%\\packages\NUnit.Console.3.0.1\tools\nunit3-console.exe' – Nick Baker Feb 18 '16 at 14:13
2

Build is running on an agent, so you need to install NUnit3 on all of the agents where you want to run a build.

Pavel Sher
  • 2,201
  • 14
  • 14
  • 5
    You also have to add the path to nunit console in TC build config, such as C:\Program Files (x86)\NUnit.org\nunit-console\nunit3-console.exe. This seems awkward now - if I set the dropdown to Nunit 3 I'd expect TeamCity to be able to bundle/resolve Nunit on its own as before. Now it feels like it's not much better off than just including a manual command line build step to shell out to Nunit on our own. – Geoffrey Hudik Dec 04 '15 at 17:56
2

There are some gotchas around the TeamCity runner - specifically, its default behaviour is not to run the specs in their own AppDomains with their own base directory, as per NUnit2 (and the NUnit3 Visual Studio Test Adapter).

There is a (currently undocumented) configuration property in the TeamCity 9.x build series that enables you to change this behaviour. I've written about it here.

Matthew Adams
  • 464
  • 3
  • 6
  • NUnit runner will have the field "Working directory" in **TC v10**. The working directory will be equal to AppDomain's ApplicationBase and will be equal to the directory of the testing assembly if it is not specified. – NikolayP Apr 28 '16 at 09:34
  • So wish this was in the jetbrains documentation. Would have saved me a lot of time. Thank you, sir. – alt_tab Nov 08 '16 at 16:05
2

Try latest version of script @NathanAldenSr

Still required variable http://teamcityserver/admin/editProject.html?projectId=yourId&tab=projectParams add nunit.consolerunner.directory parameter to Configuration Parameters

$SrcDirectory = "%teamcity.build.checkoutDir%"
$PackagesDirectory = Join-Path $SrcDirectory packages

Write-Output "PackagesDirectory" $PackagesDirectory

$NUnitConsoleRunnerPackageDirectory = Get-ChildItem (Join-Path $PackagesDirectory NUnit.ConsoleRunner.*) | %{
    @{
        Directory = $_.FullName
        Version = [Version]::Parse(($_.Name -replace "NUnit.ConsoleRunner.",""))
    }
} | Sort-Object Version -Descending | Select-Object -First 1 | %{ $_.Directory }

if (!$NUnitConsoleRunnerPackageDirectory) {
    throw [IO.DirectoryNotFoundException] "NUnit console runner package directory not found"
}

$NUnitConsoleRunnerPackageDirectory = Join-Path $NUnitConsoleRunnerPackageDirectory tools

Write-Output "NUnitConsoleRunnerPackageDirectory" $NUnitConsoleRunnerPackageDirectory
Write-Output "##teamcity[setParameter name='nunit.consolerunner.directory' value='$NUnitConsoleRunnerPackageDirectory']"
RouR
  • 6,136
  • 3
  • 34
  • 25
2

Also building on @NikolayP's answer:

NuGet currently supports the command line argument -ExcludeVersion for the install operation. From the docs:

Installs the package to a folder named with only the package name and not the version number.

This results in a path that is rather easy to use in a subsequent NUnit runner build step and allows to drop the clever workaround of @NathanAldenSr.

As of TeamCity 2017.1.3 (and probably earlier versions), this feature is even exposed as a parameter for the NuGet Installer runner (see the Restore Options) but requires a solution path. The example below is suitable for a generic on-the-fly and transient installation of NUnit.

screenshot of example build step

For easy copy and paste (adjust the NUnit version to your requirements):

  • Executable: %teamcity.tool.NuGet.CommandLine.DEFAULT%\tools\nuget.exe
  • Parameters: install NUnit.Console -Version 3.7.0 -ExcludeVersion -OutputDirectory %system.teamcity.build.tempDir%\NUnit
CodeFox
  • 3,321
  • 1
  • 29
  • 41
0

I know that it is now July of 2018, but none of these answers were clear to me. Why do I need to install a console on each agent. There has to be a better way. When I was adding my Build Step for running tests, I noticed that the text under the input for the path to the NUnit console tool said, "Paths relative to the checkout directory are supported." All I did was added the nuget packages to my test project in my solution. I added the NUnit version v3.10.1 and then the NUnit.Console v3.8.0. Then in Team City I simply added the relative path "packages\NUnit.ConsoleRunner.3.8.0\tools\nunit3-console.exe"

Kirby
  • 1,739
  • 1
  • 17
  • 21
  • If one of your unit test projects already has the `NUnit.Console` package installed, you can use that and don't need to install it separately. On the other hand I prefer not to install packages that are not needed to build and run the tests on a developer machine and to keep details related to the build machine as much out of the project files as possible. With [this answer](https://stackoverflow.com/a/45877204/1811525) it is possible without further ado. – CodeFox Mar 21 '19 at 05:05