Documentation
¶
Overview ¶
Package dockertesting provides a Go library for running go test inside Docker containers.
This library enables running tests for any Go package inside a Docker container with custom DNS aliases, network configuration, and support for nested testcontainers. It is particularly useful when tests need:
- Custom DNS resolution via container network aliases
- Tests that spin up their own testcontainers (e.g., PostgreSQL, Redis) while communicating with them via the same Docker network
- Isolated test environments that don't affect the host
Basic Usage ¶
The main entry point is the Run function which takes a package path and options:
result, err := dockertesting.Run(ctx, "./mypackage")
if err != nil {
log.Fatal(err)
}
fmt.Printf("Exit code: %d\n", result.ExitCode)
fmt.Printf("Coverage:\n%s\n", result.Coverage)
DNS Aliases ¶
To make the test container accessible via custom DNS names within the network:
result, err := dockertesting.Run(ctx, "./mypackage",
dockertesting.WithAliases("myapp.test", "api.local"),
)
Nested Testcontainers ¶
For tests that use testcontainers-go internally, enable Docker socket mounting:
result, err := dockertesting.Run(ctx, "./mypackage",
dockertesting.WithVarSock(),
)
The TESTCONTAINERS_DOCKER_NETWORK environment variable is automatically set in the container, allowing nested testcontainers to attach to the same network.
Additional Options ¶
Configure test patterns, timeouts, and additional go test arguments:
result, err := dockertesting.Run(ctx, "./mypackage",
dockertesting.WithPattern("./..."),
dockertesting.WithArgs("-v", "-race"),
dockertesting.WithTimeout(5 * time.Minute),
)
Results ¶
The Run function returns a Result containing:
- Stdout: Combined stdout/stderr from the test execution
- Coverage: The coverage profile bytes (from -coverprofile)
- ExitCode: The exit code from go test (0 = success)
Output is also streamed to os.Stdout/os.Stderr in real-time during execution.
Cleanup ¶
All Docker resources (networks and containers) are automatically cleaned up regardless of success or failure.
Index ¶
- Constants
- type CreateContainerConfig
- type DockerNetwork
- type ExecConfig
- type ExecResult
- type Option
- type Options
- type Result
- type TestContainer
- func (c *TestContainer) Container() testcontainers.Container
- func (c *TestContainer) CopyCoverage(ctx context.Context) ([]byte, error)
- func (c *TestContainer) CopyCoverageFromPath(ctx context.Context, coveragePath string) ([]byte, error)
- func (c *TestContainer) CopyFileFromContainer(ctx context.Context, containerFilePath string) ([]byte, error)
- func (c *TestContainer) ExecTest(ctx context.Context, cfg ExecConfig) (*ExecResult, error)
- func (c *TestContainer) Terminate(ctx context.Context) error
- type TimeoutError
Constants ¶
const DefaultCoverageFile = "/tmp/coverage.txt"
DefaultCoverageFile is the default path where coverage output is written inside the container.
const DefaultExecTimeout = 10 * time.Minute
DefaultExecTimeout is the default timeout for test execution.
const DefaultPattern = "./..."
DefaultPattern is the default test pattern used when none is specified.
const DefaultSockPath = "/var/run/docker.sock"
DefaultSockPath is the default Docker socket path.
const DefaultTimeout = 10 * time.Minute
DefaultTimeout is the default timeout for test execution (10 minutes).
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type CreateContainerConfig ¶
type CreateContainerConfig struct {
// PackagePath is the absolute path to the Go package to test.
PackagePath string
// Network is the Docker network to attach the container to.
Network *DockerNetwork
// Aliases are DNS aliases for the container within the network.
Aliases []string
// EnableVarSock enables mounting the Docker socket into the container.
EnableVarSock bool
// SockPath is the path to the Docker socket on the host.
SockPath string
// NetworkName is the name of the Docker network (for env var).
NetworkName string
}
CreateContainerConfig holds the configuration needed to create a test container.
type DockerNetwork ¶
type DockerNetwork struct {
// Name is the name of the Docker network.
Name string
// contains filtered or unexported fields
}
DockerNetwork wraps a testcontainers Docker network and provides access to the network name and cleanup functionality.
func CreateNetwork ¶
CreateNetwork creates a new Docker network using testcontainers-go. The network is created with an auto-generated name and can be used to attach containers.
The caller is responsible for cleaning up the network by calling the cleanup function returned, or by calling network.Remove(ctx).
func (*DockerNetwork) Network ¶
func (n *DockerNetwork) Network() *testcontainers.DockerNetwork
Network returns the underlying testcontainers.DockerNetwork for use with network.WithNetwork() when attaching containers.
type ExecConfig ¶
type ExecConfig struct {
// Pattern is the test pattern to run (e.g., "./...").
Pattern string
// Args are additional arguments to pass to go test.
Args []string
// CoverageFile is the path inside the container where coverage output is written.
CoverageFile string
// Timeout is the maximum duration for test execution.
Timeout time.Duration
}
ExecConfig holds the configuration for executing tests in the container.
type ExecResult ¶
type ExecResult struct {
// Stdout contains the combined stdout/stderr output from the test execution.
Stdout []byte
// ExitCode is the exit code from the test execution.
// 0 indicates success, non-zero indicates failure.
ExitCode int
}
ExecResult holds the result of test execution.
type Option ¶
type Option func(*Options)
Option is a functional option for configuring Options.
func WithAliases ¶
WithAliases sets DNS aliases for the container within the Docker network. Other containers on the same network can reach this container using these names. This is useful for tests that need to connect to services via custom hostnames.
Multiple calls to WithAliases are cumulative.
Example:
dockertesting.Run(ctx, path, dockertesting.WithAliases("myapp.test", "api.local"))
func WithArgs ¶
WithArgs sets additional arguments to pass to go test. These are appended after the pattern. Common examples include "-v" for verbose output, "-race" for race detection, or "-count=1" to disable test caching.
Multiple calls to WithArgs are cumulative.
Example:
dockertesting.Run(ctx, path, dockertesting.WithArgs("-v", "-race"))
func WithPattern ¶
WithPattern sets the test pattern to run. The pattern is passed to go test and follows the same syntax (e.g., "./...", "./pkg/...", "TestFoo"). If not set, defaults to "./..." to run all tests.
Example:
dockertesting.Run(ctx, path, dockertesting.WithPattern("./api/..."))
func WithSockPath ¶
WithSockPath sets the path to the Docker socket on the host. Only relevant when WithVarSock() is also used. Defaults to "/var/run/docker.sock".
Example:
dockertesting.Run(ctx, path,
dockertesting.WithVarSock(),
dockertesting.WithSockPath("/custom/docker.sock"),
)
func WithTimeout ¶
WithTimeout sets the maximum duration for the entire test execution. If the timeout is reached, the operation will be cancelled and a TimeoutError returned. Defaults to 10 minutes.
Example:
dockertesting.Run(ctx, path, dockertesting.WithTimeout(5 * time.Minute))
func WithVarSock ¶
func WithVarSock() Option
WithVarSock enables mounting the Docker socket into the container. This is required when the tests inside the container use testcontainers-go or otherwise need to interact with Docker.
The socket is mounted from the host's SockPath (default: /var/run/docker.sock) to /var/run/docker.sock inside the container.
When enabled, the TESTCONTAINERS_DOCKER_NETWORK environment variable is also set in the container, allowing nested testcontainers to attach to the same network.
Example:
dockertesting.Run(ctx, path, dockertesting.WithVarSock())
type Options ¶
type Options struct {
// PackagePath is the path to the Go package to test (required).
PackagePath string
// Pattern is the test pattern to run (default: "./...").
Pattern string
// Args are additional arguments to pass to go test.
Args []string
// Aliases are DNS aliases for the container.
Aliases []string
// EnableVarSock enables mounting the Docker socket into the container.
EnableVarSock bool
// SockPath is the path to the Docker socket on the host (default: "/var/run/docker.sock").
SockPath string
// Timeout is the maximum duration for the entire test execution (default: 10 minutes).
Timeout time.Duration
}
Options holds the configuration for running tests in a Docker container.
type Result ¶
type Result struct {
// Stdout contains the combined stdout/stderr output from the test execution.
Stdout []byte
// Coverage contains the coverage file contents as bytes.
// May be nil if coverage was not generated (e.g., tests failed early).
Coverage []byte
// ExitCode is the exit code from the test execution.
// 0 indicates success, non-zero indicates test failures.
ExitCode int
}
Result holds the result of running tests in a Docker container.
func Run ¶
Run executes go test for the given package path inside a Docker container.
It creates a Docker network, builds and starts a container with the package, executes the tests with coverage profiling, and returns the results.
The function ensures cleanup of all resources (network and container) regardless of success or failure. Stdout/stderr are forwarded to os.Stdout/os.Stderr in real-time.
Example:
result, err := dockertesting.Run(ctx, "./mypackage",
dockertesting.WithAliases("myapp.test"),
dockertesting.WithVarSock(),
)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Exit code: %d\n", result.ExitCode)
fmt.Printf("Coverage:\n%s\n", result.Coverage)
type TestContainer ¶
type TestContainer struct {
// contains filtered or unexported fields
}
TestContainer wraps a testcontainers container for running Go tests.
func CreateContainer ¶
func CreateContainer(ctx context.Context, cfg CreateContainerConfig) (*TestContainer, error)
CreateContainer builds and creates a Docker container for running Go tests. The container is built from the package at PackagePath using the embedded Dockerfile template. The container is attached to the provided network with optional aliases.
The container starts with "sleep infinity" to keep it alive for executing tests via Exec.
The caller is responsible for terminating the container by calling Terminate().
func (*TestContainer) Container ¶
func (c *TestContainer) Container() testcontainers.Container
Container returns the underlying testcontainers.Container.
func (*TestContainer) CopyCoverage ¶
func (c *TestContainer) CopyCoverage(ctx context.Context) ([]byte, error)
CopyCoverage is a convenience method that copies the coverage file from the default location. It returns the coverage file contents as bytes, or nil if the file doesn't exist.
func (*TestContainer) CopyCoverageFromPath ¶
func (c *TestContainer) CopyCoverageFromPath(ctx context.Context, coveragePath string) ([]byte, error)
CopyCoverageFromPath copies the coverage file from a custom path inside the container. It returns the coverage file contents as bytes, or nil if the file doesn't exist.
func (*TestContainer) CopyFileFromContainer ¶
func (c *TestContainer) CopyFileFromContainer(ctx context.Context, containerFilePath string) ([]byte, error)
CopyFileFromContainer copies a file from the container and returns its contents as bytes. If the file doesn't exist, it returns nil bytes and a nil error. This is useful for extracting coverage files which may not exist if tests failed early.
func (*TestContainer) ExecTest ¶
func (c *TestContainer) ExecTest(ctx context.Context, cfg ExecConfig) (*ExecResult, error)
ExecTest runs `go test` inside the container and returns the result. The command includes coverage profiling to /tmp/coverage.txt by default.
The method captures stdout/stderr and returns them along with the exit code. A non-zero exit code typically indicates test failures.
type TimeoutError ¶
TimeoutError represents an error that occurred due to a timeout.
func (*TimeoutError) Error ¶
func (e *TimeoutError) Error() string
func (*TimeoutError) Unwrap ¶
func (e *TimeoutError) Unwrap() error