Search code examples
environment-variablesnunitvisual-studio-2019visual-studio-debuggingtest-explorer

Passing environment variables to tests in Visual Studio 2019


Seems like a pretty trivial question, but to my surprise I found no mention of this on the web.

I've got an Nunit test project (that someone else wrote and I don't want to change too much), that I need to debug. These tests depend on environment variables that they read using Environment.GetEnvironmentVariable.

My question is: is there a way I can pass environment variables when debugging tests in Visual Studio?

I know I can pass environment variables when I debug an executable project through Project Properties->Debug, but this doesn't take effect when running tests (e.g. via Test Explorer). I also know I can pass test parameters through a .runsettings files, but these are accessible only through the TestContext class.


Solution

  • I also know I can pass test parameters through a .runsettings files, but these are accessible only through the TestContext class.

    You can also specify environment variables in the .runsettings file:

    <?xml version="1.0" encoding="utf-8"?>
    <RunSettings>
        <RunConfiguration>
            <EnvironmentVariables>
                <YOUR_VARIABLE>Value for your variable</YOUR_VARIABLE>
                <SOME_OTHER_VARIABLE>With another Value</SOME_OTHER_VARIABLE>
            </EnvironmentVariables>
        </RunConfiguration>
    </RunSettings>
    

    Alternatively (if you need to run code or calculate the value) you can implement a DataCollector which provides environment variables via ITestExecutionEnvironmentSpecifier

    // Add a reference to nuget package `Microsoft.TestPlatform.ObjectModel`
    // The assembly name must end with `Collector` (i.e. match `*collector.dll`)
    
    [DataCollectorFriendlyName("my own example collector")]
    [DataCollectorTypeUri("datacollector://myown/examplecollector/1.0")]
    public class MyDataCollector : DataCollector, ITestExecutionEnvironmentSpecifier
    {
        public override void Initialize(
            XmlElement configurationElement,
            DataCollectionEvents events,
            DataCollectionSink dataSink,
            DataCollectionLogger logger,
            DataCollectionEnvironmentContext environmentContext)
        {
            // inspect configurationElement for your custom settings
        }
    
        public IEnumerable<KeyValuePair<string, string>> GetTestExecutionEnvironmentVariables()
        {
            return new Dictionary<string, string>
            {
                ["YOUR_VARIABLE"] = "your value",
            };
        }
    }
    

    You also configure your data collector via the .runsettings file:

    <?xml version="1.0" encoding="utf-8"?>
    <RunSettings>
        <RunConfiguration>
            <TestAdaptersPaths>path/where/to/find/your/collector</TestAdaptersPaths>
        </RunConfiguration>
        <DataCollectionRunSettings>
            <DataCollectors>
                <DataCollector friendlyName="my own example collector" uri="datacollector://myown/examplecollector/1.0">
                    <Configuration>
                        <SomeSettingHere/>
                    </Configuration>
                </DataCollector>
            </DataCollectors>
        </DataCollectionRunSettings>
    </RunSettings>