Should GetEnvironmentVariable work in xUnit tests?

.net-core, visual-studio, visual-studio-2017, xunit.net

Solution

The `GetEnvironmentVariable` works fine in xUnit tests. The problem is to properly set a variable. If you set the variable at `Properties -> Debug` page, then the variable is written to `Properties\launchSettings.json` and Visual Studio makes all work to launch an application with the selected profile. As you could see, `launchSettings.json` even isn't copied to output folder by default. It's impossible to pass this file as argument to `dotnet run` or `dotnet test`, that leads to obvious problem if tests are run automatically on a CI server. So it is not surprising that `launchSettings.json` isn't considered by a test runner.

Solution: there are a lot of ways to setup a test environment in xUnit:

- Constructor

- Base class

- Fixture

For example, this collection fixture sets up all environment variables from `launchSettings.json`:

public class LaunchSettingsFixture : IDisposable
{
    public LaunchSettingsFixture()
    {
        using (var file = File.OpenText("Properties\\launchSettings.json"))
        {
            var reader = new JsonTextReader(file);
            var jObject = JObject.Load(reader);

            var variables = jObject
                .GetValue("profiles")
                //select a proper profile here
                .SelectMany(profiles => profiles.Children())
                .SelectMany(profile => profile.Children<JProperty>())
                .Where(prop => prop.Name == "environmentVariables")
                .SelectMany(prop => prop.Value.Children<JProperty>())
                .ToList();

            foreach (var variable in variables)
            {
                Environment.SetEnvironmentVariable(variable.Name, variable.Value.ToString());
            }
        }
    }

    public void Dispose()
    {
        // ... clean up
    }
}

Set `Copy to output directory: Always` for `launchSettings.json` to make the file accessible from tests.

Problem

If I set environment variables for a .Net Core web project in Visual Studio 2017 using the project properties page, I can read the value of the variable using `Environment.GetEnvironmentVariable`; however, when I set the environment variable for my xUnit testing project and then debug the test, `Environment.GetEnvironmentVariable` always returns null. Is there something about the fact that it is a testing project that should prevent the variable from being used the same as with the web project? If so, is there a way that I can set the environment variables for a test project? Thank you.

Original source