testcontainers-go

Testcontainers is a Golang library that providing a friendly API to run Docker container. It is designed to create runtime environment to use during your automatic tests.

Github星跟踪图

Build Status

When I was working on a Zipkin PR I discovered a nice Java library called
testcontainers.

It provides an easy and clean API over the go docker sdk to run, terminate and
connect to containers in your tests.

I found myself comfortable programmatically writing the containers I need to run
an integration/smoke tests. So I started porting this library in Go.

This is the API I have defined:

package main

import (
	"context"
	"fmt"
	"net/http"
	"testing"

	"github.com/testcontainers/testcontainers-go"
	"github.com/testcontainers/testcontainers-go/wait"
)

func TestNginxLatestReturn(t *testing.T) {
	ctx := context.Background()
	req := testcontainers.ContainerRequest{
		Image:        "nginx",
		ExposedPorts: []string{"80/tcp"},
		WaitingFor:   wait.ForHTTP("/"),
	}
	nginxC, err := testcontainers.GenericContainer(ctx, testcontainers.GenericContainerRequest{
		ContainerRequest: req,
		Started:          true,
	})
	if err != nil {
		t.Error(err)
	}
	defer nginxC.Terminate(ctx)
	ip, err := nginxC.Host(ctx)
	if err != nil {
		t.Error(err)
	}
	port, err := nginxC.MappedPort(ctx, "80")
	if err != nil {
		t.Error(err)
	}
	resp, err := http.Get(fmt.Sprintf("http://%s:%s", ip, port.Port()))
	if resp.StatusCode != http.StatusOK {
		t.Errorf("Expected status code %d. Got %d.", http.StatusOK, resp.StatusCode)
	}
}

This is a simple example, you can create one container in my case using the
nginx image. You can get its IP ip, err := nginxC.GetContainerIpAddress(ctx) and you
can use it to make a GET: resp, err := http.Get(fmt.Sprintf("http://%s", ip))

To clean your environment you can defer the container termination defer nginxC.Terminate(ctx, t). t is *testing.T and it is used to notify is the
defer failed marking the test as failed.

Build from Dockerfile

Testcontainers-go gives you the ability to build an image and run a container from a Dockerfile.

You can do so by specifying a Context (the filepath to the build context on your local filesystem)
and optionally a Dockerfile (defaults to "Dockerfile") like so:

req := ContainerRequest{
		FromDockerfile: testcontainers.FromDockerfile{
			Context: "/path/to/build/context",
			Dockerfile: "CustomDockerfile",
		},
	}

Dynamic Build Context

If you would like to send a build context that you created in code (maybe you have a dynamic Dockerfile), you can
send the build context as an io.Reader since the Docker Daemon accepts is as a tar file, you can use the tar package to create your context.

To do this you would use the ContextArchive attribute in the FromDockerfile struct.

var buf bytes.Buffer
tarWriter := tar.NewWriter(&buf)
// ... add some files
if err := tarWriter.Close(); err != nil {
	// do something with err
}
reader := bytes.NewReader(buf.Bytes())
fromDockerfile := testcontainers.FromDockerfile{
	ContextArchive: reader,
}

Please Note if you specify a ContextArchive this will cause testcontainers to ignore the path passed
in to Context

Sending a CMD to a Container

If you would like to send a CMD (command) to a container, you can pass it in to the container request via the Cmd field...

req := ContainerRequest{
	Image: "alpine",
	WaitingFor: wait.ForAll(
		wait.ForLog("command override!"),
	),
	Cmd: []string{"echo", "command override!"},
}

主要指标

概览
名称与所有者testcontainers/testcontainers-go
主编程语言Go
编程语言Go (语言数: 5)
平台
许可证MIT License
所有者活动
创建于2018-07-18 15:04:31
推送于2025-06-19 06:35:42
最后一次提交
发布数841
最新版本名称modules/dockermodelrunner/v0.37.2 (发布于 )
第一版名称0.0.1 (发布于 )
用户参与
星数4.1k
关注者数16
派生数547
提交数2.2k
已启用问题?
问题数542
打开的问题数95
拉请求数1487
打开的拉请求数43
关闭的拉请求数1096
项目设置
已启用Wiki?
已存档?
是复刻?
已锁定?
是镜像?
是私有?