0
votes

I am using this ICollectionFixture setup

[CollectionDefinition("BaseCollection")]
public class Collection : ICollectionFixture<TestContext>
{ }

The TestContext is setup like this:

    public TestContext()
    {
        var builder = new ConfigurationBuilder().
            SetBasePath(Environment.CurrentDirectory).
            AddJsonFile("local.settings.json", optional: true, reloadOnChange: true).
            AddEnvironmentVariables();

        Configuration = builder.Build();

        var serviceCollection = new ServiceCollection();
        var connectionString = 
            Configuration.GetConnectionString("MyDbContext") ?? 
            Configuration.GetValue<string>("Values:MyDbContext") ??
            Configuration.GetValue<string>("MyDbContext") ??
            Environment.GetEnvironmentVariable("MyDbContext");


        serviceCollection.AddDbContext<MyDbContext>(options => options.UseSqlServer(connectionString), ServiceLifetime.Transient);
        ServiceProvider = serviceCollection.BuildServiceProvider();
    }

The Test class looks like this:

[Collection("BaseCollection")]
public class MyIntegrationTestClass
{
    private readonly MyDbContext context;

    public MyIntegrationTestClass(TestContext testContext)
    {
        this.context = testContext.ServiceProvider.GetService<MyDbContext>();
    }
}

My Azure DevOps pipeline variables: Azure DevOps pipeline variables

Note that I have the following step in my YAML:

steps:
- script: echo Building with PR using ConnectionString '$(MyDbContext)'

The result from this is this print:

echo Building with PR using ConnectionString '***'

The conclusion I have drawn from this is that the environment variable is found in the pipeline but somehow not in the TestContext.

For some reason the environment variables are always null, if I use my local.settings.json it works fine. The only step in my pipeline that does not work is the test part (build, restore, pack and publish works fine). Any ideas?

2
Have you tried creating a test console app, using ConfigurationBuilder.AddEnvironmentVariables() and the other APIs, to make sure it works as you think it does? With a console app, you can set Visual Studio's debug options to set the environment variables for debugging, and then step through the code to see what values are in the configuration objects to better understand why it's not getting the value you expect. - zivkan
Good point @zivkan, I have tried that actually and the result was the same. I feel I am missing something really simple. - Marcus
I'm confused as to what problem you're actually experiencing. I created a console app and did var builder = new ConfigurationBuilder().AddEnvironmentVariables();, var configuration = builder.Build();, Console.WriteLine("Username = " + configuration["USERNAME"]);, and it worked just fine. It would be helpful if you could better explain what part specifically isn't working (is the value there in the TestContext constructor, or is the problem with the value returned from testContext.ServiceProvider.GetService<MyDbContext>()? Maybe you need to make more effort to isolate the issue? - zivkan
Any chance these are case sensitive? The agent upper-cases them and replaces any non-alphanumeric characters with _. - jessehouwing
Good idea @jessehouwing, unfortunately casing is not the issue (tried all lower and all upper in both project and pipeline variables). - Marcus

2 Answers

1
votes

I ever meet the same issue with you. While I pass a secret variable to docker, it failed with value= null.

This caused by you are using secret variable with YAML. In fact, the doc has been said that:

You should not set secret variables in your YAML file. Instead, you should set them in the pipeline editor using the web interface. These variables are scoped to the pipeline in which you set them.

And also, in this doc, you can see that Azure Devops recommend map secrets variable into environment variables.

enter image description here

That's why you receive the null value, you need to map it as environment variable first while you are using YAML and command line. Or the server could not analytic its value correctly.

You can refer to this doc, change your bash script as the below format:

- script: echo $MYSECRET
  env:
    MySecret: $(Foo)

Note: Foo is the secret variable name.

0
votes

The problem in my case was that I was running a self-hosted agent in DevOps and the fix was simply to restart the build agent.