Setting environment variables in .runsettings file results in different behaviour

983 Views Asked by At

For demo purposes I made a project demonstrating the possibilities of NUnit.

I also added a demo.runsettings file based on the examples of Microsoft.

At first I had the 'DOTNET_ROOT` variable set in this file. From within Visual Studio the test succeeded without a problem.

But with this variable set in the .runsettings file and the unit tests ran from the command line with:

dotnet test -l "console;verbosity=detailed" -c Release

The test execution failed with this output:

System.ArgumentException: An item with the same key has already been added. Key: DOTNET_ROOT at System.Collections.Generic.Dictionary2.TryInsert(TKey key, TValue value, InsertionBehavior behavior) at System.Collections.Generic.Dictionary2.Add(TKey key, TValue value)
at Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Hosting.DotnetTestHostManager.GetTestHostProcessStartInfo(IEnumerable1 sources, IDictionary2 environmentVariables, TestRunnerConnectionInfo connectionInfo) at Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Client.ProxyOperationManager.SetupChannel(IEnumerable`1 sources, String runSettings) at Microsoft.VisualStudio.TestPlatform.CrossPlatEngine.Client.ProxyExecutionManager.StartTestRun(TestRunCriteria testRunCriteria, IInternalTestRunEventsHandler eventHandler)

Test Run Aborted.

It seems that there is different behavior for different environment variables in the .runsettings file. Setting the variable:

  • DOTNET_ROOT cannot be overridden, otherwise you'll get the exception above.
  • SystemRoot can be overwritten, but makes the test inconclusive.
  • HOMEDRIVE can be overwritten.

So is this behavior documented? Or is it just trial and error to see what you can set?

<?xml version="1.0" encoding="utf-8"?>
<RunSettings>
  <!-- Configurations that affect the Test Framework -->
  <RunConfiguration>
    <EnvironmentVariables>
      <ANewVar>dotnet</ANewVar>
      <!-- This can't be set here! <DOTNET_ROOT>C:\ProgramFiles\dotnet</DOTNET_ROOT> -->
      <HOMEDRIVE>D:</HOMEDRIVE>
    </EnvironmentVariables>
  </RunConfiguration>

  <!-- Parameters used by tests at runtime -->
  <TestRunParameters>
    <Parameter name="webAppUrl" value="http://localhost" />
    <Parameter name="webAppUserName" value="Admin" />
    <Parameter name="webAppPassword" value="Password" />
  </TestRunParameters>

</RunSettings>

The file is referenced in the project file:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>net7.0</TargetFramework>
    <RunSettingsFilePath>$(MSBuildProjectDirectory)\demo.runsettings</RunSettingsFilePath>
  </PropertyGroup>

  <!-- Rest deleted... -->
</Project>

The NUnit test that uses the environment variable from the .runsettings file:

  [Test]
  public void Example()
  {
    static void AssertAndTestValue(List<DictionaryEntry> variables, string key, string expectedValue)
    {
      var keyValue = variables.Find(ev => string.Equals(ev.Key.ToString(), key, StringComparison.CurrentCultureIgnoreCase));
      Assert.That(keyValue.Value, Is.Not.Null);
      Assert.That(keyValue.Value, Is.EqualTo(expectedValue).IgnoreCase);
    }

    var environmentVariables = Environment.GetEnvironmentVariables()
      .Cast<DictionaryEntry>()
      .OrderBy(ev => ev.Key)
      .ToList();

    Assert.Multiple(() =>
    {
      Assert.That(environmentVariables, Is.Not.Null);
      Assert.That(environmentVariables, Is.Not.Empty);
    });

    // Environment variable from demo.runsettings
    // This fails when run from the command line! AssertAndTestValue(environmentVariables, "DOTNET_ROOT", "C:\\ProgramFiles\\dotnet");
    AssertAndTestValue(environmentVariables, "ANewVar", "dotnet");
    AssertAndTestValue(environmentVariables, "HOMEDRIVE", "D:");
  }
0

There are 0 best solutions below