Automated tests, no matter on which test level, always needs some set of constant values in order to run e.g. application URL. Also, this URL might depend on environment on which tests are executed.

It's not a good practice to hard code those values in code. Much better approach is to move it to configuration files. This post is the first from series of articles where you learn how to use configuration in C# projects.

This article will guide you step by step how to create first configuration file, load it and make its values available to your tests. All code is published on our github repository so feel free to clone it and test locally!

Part 1 - single file with single value

Step 0 - Create project

It can be any type of project but it this article I will use xUnit project and .NET 6.0

Step 1 - Add configuration files

Configuration file can be of any type but I strongly recommend to use JSON format - it is easy to read by human and can be easily handled by code.

  1. In Solution Explorer, Right-click on project and select Add -> New item...

  1. Select Text File, set name e.g. appSettings.json and click Add.
  2. Right-click added file in Solution Explorer and click Properties
    Set Copy to Output Directory from Do not copy to Copy if newer
  3. Click added file in Solution Explorer
  4. Write first settings value and save
{
  url: app.dev.myapp.com;
}

Now you have first value stored in configuration file!

Step 2 - Add configuration model

It would be convenient if configuration file could be read and converted into C# object so getting values is easy e.g. string url = settings.Url;
To do that, a model is needed which maps all elements from JSON into class properties.

  1. Right-click on your project and select Add -> New folder
    Set name Models
  2. Right-click on Models folder and select Add -> Class...
    Set name Settings.cs
  3. Open class Settings and add property
    public string Url {get; set;} = default!;

Name of property is important here - it must be the same as name in JSON! Note that case is no important so Url property is OK for url value in JSON.

Note that = default! is IMHO best way to get rid of Warning CS8618 Non-nullable property \'Url\' must contain a non-null value when exiting constructor.

Settings.cs should look as below:

namespace QaServices.TestConfigurationDemo.Models
{
    internal class Settings
    {
        public string Url { get; set; } = default!;
    }
}

Step 3 - Load appSettings.json and bind it to Settings model

.NET provides library to handle configuration files, so first install needed packages

  • Microsoft.Extensions.Configuration
  • Microsoft.Extensions.Configuration.Files
  • Microsoft.Extensions.Configuration.Json
  • Microsoft.Extensions.Configuration.Binder

You can install packages using NuGet Package Manager or by running commands below in Package Manager Console:

dotnet add .\QaServices.TestConfigurationDemo.csproj package Microsoft.Extensions.Configuration

dotnet add .\QaServices.TestConfigurationDemo.csproj package Microsoft.Extensions.Configuration.FileExtensions

dotnet add .\QaServices.TestConfigurationDemo.csproj package Microsoft.Extensions.Configuration.Json

dotnet add .\QaServices.TestConfigurationDemo.csproj package Microsoft.Extensions.Configuration.Binder

Now let\'s load configuration from file! Create folder Tests and add new class named BasicConfigurationTests.cs inside. Add xUnit output helper so we can see results.

using Xunit.Abstractions;

namespace QaServices.TestConfigurationDemo.Tests
{
    public class BasicConfigurationTests
    {
        private readonly ITestOutputHelper _output;

        public BasicConfigurationTests(ITestOutputHelper output) => _output = output;

        [Fact]
        public void TestUrlIsLoaded()
        {}
    }
}

In method TestUrlIsLoaded add following code:

IConfigurationBuilder builder = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appSettings.json", optional: false);

IConfiguration configuration = builder.Build();

Settings settings = new();

configuration.Bind(settings);

_output.WriteLine($"Url from config: {settings.Url}");

Add missing usings

using Microsoft.Extensions.Configuration;
using QaServices.TestConfigurationDemo.Models;

Now execute test TestUrlIsLoaded! Test should pass and config value should be displayed in Test Detail Summary as below:

What happened? Let's analyse the code line by line

var builder = new ConfigurationBuilder()
                .SetBasePath(Directory.GetCurrentDirectory())
                .AddJsonFile("appSettings.json", optional: false);
  • new ConfigurationBuilder() - creating object responsible for storing configuration sources (might be more than one!)
  • SetBasePath(path) - phisical path on disc where we will look for config files.
  • Directory.GetCurrentDirectory() - our build directory e.g. test-configuration-demo\QaServices.TestConfigurationDemo\bin\Debug\net6.0\ so the directory where binaries are created and file appSettings.json is copied (thanks to step 1.3)
  • AddJsonFile() - adding file of type JSON to builder
  • optional: false - when appSettings.json does not exist in BasePath directory, exception is thrown
  • IConfiguration configuration = builder.Build(); - load all configuration sources and create configuration object
  • Settings settings = new(); - we need to initialize empty object first in order to be able to assign its properties
  • configuration.Bind(settings); - here\'s the magic - JSON config is mapped to the model - JSON value for url is assigned to Url property in settings object and then can be accessed by settings.Url.
  • It\'s normal C# object so you can do whatever you want with it - assign to variable string url = settings.Url; or add into string and pass as argument like here:
    _output.WriteLine($Url from config: {settings.Url});

In part 2 I will focus on more complex JSON files with other data types, nested values and arrays. If you want to get notified when new post is published, sign up to our newsletter!