How to specify to NUnit test runner to execute tests in 64 bits

3.4k views Asked by At

I've a lot of UnitTests, which are all configure as AnyCPU. We would like them to run as x64 on the BUILD machine. The build machine is a Jenkins server that runs basically the NUNIT console runner:

C:\nunit-console\nunit3-console.exe path-to-my-solution.sln --config=Debug --agents=1 --process=Separate --result=TestResult.xml;format=nunit2 --timeout=300000 --workers=1

For test purpose I've this Unit Test:

[Test]
public void TestProcess()
{
    Assert.AreEqual(Environment.Is64BitProcess, true);
}

On Visual Studio, if I go to Test -> Test Settings -> Default Processor Architecture, it fails if I select x86, but success if I select x64.

Is there a way to have the same behavior when executing directly the tests throught the nunit3-console.exe WITHOUT changing the platform in the test project(not the goal of discussing it here, let's just admit we have some reason to keep it as "Any CPU").

I've found this https://msdn.microsoft.com/en-us/library/ee782531.aspx which explains that to do this on Visual studio, we can either choose my approach, either choose to create a test.runsettings.

I tried to create a test.runsettings file, with the following content:

<?xml version="1.0" encoding="utf-8"?>
<RunSettings>  
  <!-- Configurations that affect the Test Framework -->  
  <RunConfiguration>  
    <!-- [x86] | x64    
      - You can also change it from menu Test, Test Settings, Default Processor Architecture -->  
    <TargetPlatform>x64</TargetPlatform>  
  </RunConfiguration>  
</RunSettings>  

I've put it in the root of my solution and I've done the Test -> Test Settings -> Select Test Settings file. The weird part is that I've the feeling that this operation (setting this file as "Test Settings file" is not persisted when I commit, because after having done it if I take my latest changes on another computer, I've to set it again.

But my UnitTest still fails on the build machine. Any idea of an alternative or what I've done wrong here?

1

There are 1 answers

4
Charlie On

Starting from your basic question: "How to specify to NUnit [console] test runner to execute tests in 64 bits?" The answer is nothing!

Assemblies that are pure IL (AnyCpu targeted) run as a 64-bit process on a 64-bit machine with a 64-bit OS. You don't have to do anything. The console runner provides an --x86 option to run your AnyCpu code in a 32-bit process but no corresponding 64-bit option exists, because it is not needed.

There are several ways you can defeat this default: 1. Running on a 32-bit machine or under a 32-bit version of the OS 2. Forcing the tests to run in a 32-bit process 3. Running a test that targets 32 bits.

I suspect you are doing both 2 and 3.

By running the .sln file, you are asking NUnit to load every assembly specified in the solution. Because you used the --process=Separate option, you are forcing all those assemblies to load in the same process. If even one of those assemblies, including non-test assemblies requires 32 bits, then that separate process will be a 32-bit process.

Note that the --process=Separate option doesn't run each assembly in it's own process, but in a single process, separate from main process. This is slightly unintuitive if you are using it without reading the docs.

My advice is 1. Don't add any options on the command-line unless you understand what they do and find you actually need them. NUnit is designed to figure things out itself when you use the defaults but to use whatever options you provide, no matter how crazy it seems! 2. Read the docs

As a starting point, this command should work for you...

nunit3-console path-to-assembly.dll path-to-another-assembly.dll

Regarding additional options... * --process:Separate is a bad idea. Let it default to Multiple. * --agents=1 is OK if you want each process to run before the next starts. * --workers=1 only makes sense if some tests use [Parallelizable] and you are trying to disable it.

If you are using the solution because there are too many assemblies to place on the command-line, the above may work, provided every assembly is one that NUnit can load. There's a better chance of it's working with the default process setting. Otherwise, I suggest using an NUnit project.