testcontainers-dotnet

module
v1.4.6 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 13, 2019 License: MIT

README

TestContainers dotnet

codecov Sonarcloud Status Donation

Testcontainers is a dotnet standard 2.0 library that supports NUnit and XUnit tests, providing lightweight, throwaway instances of common databases or anything else that can run in a Docker container.

Uses common Microsoft dependency injection patterns, app and host settings, and Microsoft Extensions Logging (MEL).

This is a port of testcontainers-java for dotnet.

Linux: Build Status

Windows: Build status


Feature parity

Linux environment

  • Container management
  • Docker providers
    • Unix socket
    • Environment
  • Image management
    • Pulling from public repo
    • Building from docker file
  • Network management
    • User defined networks
    • Network aliases
  • Ryuk resource reaper

Windows environment

  • Container management
  • Docker providers
    • Npipe
    • Environment
  • Image management
    • Pulling from public repo
    • Building from docker file
  • Network management
    • User defined networks
    • Network aliases
  • Todo: Windows version of Ryuk [Help wanted]

Built-in containers

Container Readme Version
Generic Container -- Generic
MsSql Container README MySql
PostgreSql Container README PostgreSql
ArangoDb Container README ArangoDb

Example code

For more examples, see integration tests

Start a container by pulling the image from a remote repository
var container = new ContainerBuilder<GenericContainer>()
    .ConfigureHostConfiguration(builder => builder.AddInMemoryCollection()) // host settings
    .ConfigureAppConfiguration((context, builder) => builder.AddInMemoryCollection()) // app settings
    .ConfigureDockerImageName(PlatformSpecific.TinyDockerImage)
    .ConfigureLogging(builder => builder.AddConsole()) // Microsoft extensions logging
    .ConfigureContainer((context, container) =>
    {
        // add labels
        container.Labels.Add(CustomLabel.Key, CustomLabel.Value);
        
        // add environment labels
        container.Env[InjectedEnvVar.Key] = InjectedEnvVar.Value;
        
        // add exposed ports (automatically mapped to higher port
        container.ExposedPorts.Add(ExposedPort);

        /*
         to do something like `docker run -p 2345:34567 alpine:latest`,
         both expose port and port binding must be set
         */
        container.ExposedPorts.Add(PortBinding.Key);
        container.PortBindings.Add(PortBinding.Key, PortBinding.Value);
        
        // add bind mounts
        container.BindMounts.Add(new Bind
        {
            HostPath = HostPathBinding.Key,
            ContainerPath = HostPathBinding.Value,
            AccessMode = AccessMode.ReadOnly
        });
        
        // set working directory
        container.WorkingDirectory = WorkingDirectory;
        
        // set command to run
        container.Command = PlatformSpecific.ShellCommand(
                $"{PlatformSpecific.Touch} {FileTouchedByCommand}; {PlatformSpecific.Shell}")
            .ToList();
    })
    .Build();
Start a container by building the image from a Dockerfile
var image = new ImageBuilder<DockerfileImage>()
    .ConfigureHostConfiguration(builder => builder.AddInMemoryCollection()) // host settings
    .ConfigureAppConfiguration((context, builder) => builder.AddInMemoryCollection()) // app settings
    .ConfigureLogging(builder => builder.AddConsole()) // Microsoft extensions logging
    .ConfigureImage((context, image) =>
    {
        image.DockerfilePath = "Dockerfile";
        image.DeleteOnExit = false;

        // add the Dockerfile into the build context 
        image.Transferables.Add("Dockerfile", new MountableFile(PlatformSpecific.DockerfileImagePath));
        // add other files required by the Dockerfile into the build context
        image.Transferables.Add(".", new MountableFile(PlatformSpecific.DockerfileImageContext));
    })
    .Build();

var container = new ContainerBuilder<GenericContainer>()
    .ConfigureDockerImage(image)
    .ConfigureHostConfiguration(builder => builder.AddInMemoryCollection()) // host settings
    .ConfigureAppConfiguration((context, builder) => builder.AddInMemoryCollection()) // app settings
    .ConfigureLogging(builder => builder.AddConsole()) // Microsoft extensions logging
    .ConfigureContainer((h, c) =>
    {
        c.ExposedPorts.Add(80);
    })
    .Build();

or

var container = new ContainerBuilder<GenericContainer>()
    .ConfigureDockerImage((hostContext, builderContext) => 
    {
        return new ImageBuilder<DockerfileImage>()
            // share the app/host config and service collection from the parent builder context
            .WithContextFrom(builderContext)
            .ConfigureImage((context, image) =>
            {
                image.DeleteOnExit = false;
                image.BasePath = PlatformSpecific.DockerfileImageContext;
        
                // add the Dockerfile as like the command line `-f <path to dockerfile`
                image.DockerfilePath = "Dockerfile"; 
                image.Transferables.Add("Dockerfile", new MountableFile(PlatformSpecific.DockerfileImagePath));

                // add other files required by the Dockerfile into the build context
                image.Transferables.Add("folder1", new MountableFile(DockerfileImageTransferableFolder));
            })
            .Build();
    })
    .ConfigureHostConfiguration(builder => builder.AddInMemoryCollection()) // host settings
    .ConfigureAppConfiguration((context, builder) => builder.AddInMemoryCollection()) // app settings
    .ConfigureLogging(builder => builder.AddConsole()) // Microsoft extensions logging
    .ConfigureContainer((h, c) =>
    {
        c.ExposedPorts.Add(80);
    })
    .Build();
Start a container with a new network
var container = new ContainerBuilder<GenericContainer>()
    .ConfigureNetwork((hostContext, builderContext) => 
    {
        return new NetworkBuilder<UserDefinedNetwork>()
            // share the app/host config and service collection from the parent builder context
            .WithContextFrom(builderContext)
            .ConfigureNetwork((context, network) =>
            {
                // be careful when setting static network names
                // if they already exists, the existing network will be used
                // otherwise, the default NetworkName is a random string 
                network.NetworkName = "my_network"
            })
            .Build();
    })
    .ConfigureHostConfiguration(builder => builder.AddInMemoryCollection()) // host settings
    .ConfigureAppConfiguration((context, builder) => builder.AddInMemoryCollection()) // app settings
    .ConfigureLogging(builder => builder.AddConsole()) // Microsoft extensions logging
    .ConfigureContainer((h, c) =>
    {
        c.ExposedPorts.Add(80);
    })
    .Build();

Configuring TestContainers-dotnet

There are some configurations to testcontainers-dotnet that cannot be performed in code or injected. These configuration can be set in environment variables before the first instance of your container is built.

Variable Default Description
REAPER_DISABLED (not-set) When set to 1 or true, disables starting of the reaper container
REAPER_IMAGE quay.io/testcontainers/ryuk:0.2.3 Change which container image to use for reaper

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL