
Security News
Bun 1.2.19 Adds Isolated Installs for Better Monorepo Support
Bun 1.2.19 introduces isolated installs for smoother monorepo workflows, along with performance boosts, new tooling, and key compatibility fixes.
github.com/tmc/misc/testctr
A minimal, zero-dependency library for container-based testing in Go. Uses Docker CLI directly for simplicity and speed.
t.Parallel()
with coordination.-testctr.keep-failed
.go get github.com/tmc/misc/testctr
import "github.com/tmc/misc/testctr"
func TestMyApp(t *testing.T) {
// Create a Redis container
redis := testctr.New(t, "redis:7-alpine")
// Get connection details
addr := redis.Endpoint("6379") // "127.0.0.1:32768" (example port)
// Execute commands
output := redis.ExecSimple("redis-cli", "PING")
// output: "PONG"
}
testctr provides automatic per-test database isolation. Service-specific defaults and options are available in ctropts/<service>
packages.
import (
"database/sql"
"testing"
"github.com/tmc/misc/testctr"
"github.com/tmc/misc/testctr/ctropts/mysql" // For MySQL defaults
"github.com/tmc/misc/testctr/ctropts/postgres" // For PostgreSQL defaults
)
func TestMySQL(t *testing.T) {
// Uses MySQL defaults (port, wait strategy, DSN provider)
mysqlC := testctr.New(t, "mysql:8", mysql.Default())
// Each test gets its own database, cleaned up automatically
dsn := mysqlC.DSN(t) // e.g., "root:test@tcp(127.0.0.1:32768)/testmysql_testmysql?..."
db, _ := sql.Open("mysql", dsn)
// Test with isolated database
}
func TestPostgreSQL(t *testing.T) {
pgC := testctr.New(t, "postgres:15", postgres.Default())
dsn := pgC.DSN(t) // e.g., "postgresql://postgres@127.0.0.1:32769/testpostgresql_testpostgresql?sslmode=disable"
}
All containers are safe for parallel tests:
func TestParallel(t *testing.T) {
t.Parallel() // Safe!
mysqlC := testctr.New(t, "mysql:8", mysql.Default())
// Run parallel subtests with isolated databases
t.Run("Test1", func(t *testing.T) {
t.Parallel()
dsn := mysqlC.DSN(t) // Gets unique database for TestParallel/Test1
})
t.Run("Test2", func(t *testing.T) {
t.Parallel()
dsn := mysqlC.DSN(t) // Gets unique database for TestParallel/Test2
})
}
testctr
package)// Environment variables
c := testctr.New(t, "myapp:latest",
testctr.WithEnv("DEBUG", "true"),
testctr.WithEnv("PORT", "8080"),
)
// Ports (maps to a random host port)
c := testctr.New(t, "nginx:alpine",
testctr.WithPort("80"), // Exposes container port 80
testctr.WithPort("443/udp"), // Can specify protocol
)
// Command
c := testctr.New(t, "alpine:latest",
testctr.WithCommand("sh", "-c", "echo hello && sleep 10"),
)
testctr
package)import "strings"
// Copy a single file
c := testctr.New(t, "alpine:latest",
testctr.WithFile("./config.json", "/app/config.json"),
)
// Copy with specific permissions
c := testctr.New(t, "alpine:latest",
testctr.WithFileMode("./script.sh", "/app/script.sh", 0755),
)
// Copy from io.Reader
reader := strings.NewReader("Hello, World!")
c := testctr.New(t, "alpine:latest",
testctr.WithFileReader(reader, "/app/message.txt"),
)
// Copy multiple files using FileEntry struct
c := testctr.New(t, "alpine:latest",
testctr.WithFiles(
testctr.FileEntry{Source: "./config.json", Target: "/etc/config.json"},
testctr.FileEntry{Source: "./data.csv", Target: "/data/input.csv"},
),
)
ctropts
package)import (
"time"
"github.com/tmc/misc/testctr/ctropts"
)
c := testctr.New(t, "myapp:latest",
// Mounts
ctropts.WithBindMount("./config", "/app/config"),
// Network
ctropts.WithNetwork("host"),
// Resources
ctropts.WithMemoryLimit("512m"),
// Wait strategies
ctropts.WithWaitForLog("Server started", 30*time.Second),
ctropts.WithWaitForExec([]string{"healthcheck"}, 10*time.Second),
// ctropts.WithWaitForHTTP("/health", "8080", 200, 15*time.Second), // Example
// Runtime
ctropts.WithPodman(), // Or WithNerdctl(), WithFinch(), etc.
)
ctropts/<service>
packages)Modules provide a Default()
option and other specific configurations.
// MySQL example
import "github.com/tmc/misc/testctr/ctropts/mysql"
c := testctr.New(t, "mysql:8",
mysql.Default(), // Includes DSN support, wait strategies, common env vars
mysql.WithPassword("secret"), // Override default password
mysql.WithDatabase("myapp"), // Override default database
mysql.WithCharacterSet("utf8mb4"),
)
// PostgreSQL example
import "github.com/tmc/misc/testctr/ctropts/postgres"
c := testctr.New(t, "postgres:15",
postgres.Default(),
postgres.WithPassword("secret"),
postgres.WithDatabase("myapp"),
postgres.WithExtensions("uuid-ossp", "postgis"),
)
testctr uses a pluggable backend system. The default CLI backend uses docker/podman commands directly, providing zero dependencies and maximum compatibility.
(Same as in your original GoDoc - this section is good)
(Same as in your original GoDoc - this section is good)
*testctr.Container
)// Create container
c := testctr.New(t, "image:tag", opts...)
// Connection info
c.Host() // Container host (usually "127.0.0.1")
c.Port("3306") // Get mapped host port for a container port string (e.g., "3306" or "3306/tcp")
c.Endpoint("3306") // Get "host:port" string for a container port
c.ID() // Container ID
c.Runtime() // Runtime being used (e.g., "docker", "podman", or backend name like "testcontainers")
// Execute commands
exitCode, output, err := c.Exec(ctx, []string{"cmd", "arg"})
output := c.ExecSimple("cmd", "arg") // Panics on error, returns trimmed output
// Database support (if DSNProvider is configured, typically by module.Default())
dsn := c.DSN(t) // Get database connection string for a test-specific database
testctr
package)(Same as in your original GoDoc - this section is good)
(Same as in your original GoDoc, perhaps with a note about the pluggable backend system)
(Same as in your original GoDoc - this section is good)
(Same as in your original GoDoc - this section is good)
See the testctr-tests/
directory for comprehensive examples.
(Same as in your original GoDoc - this section is good)
MIT
FAQs
Unknown package
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
Bun 1.2.19 introduces isolated installs for smoother monorepo workflows, along with performance boosts, new tooling, and key compatibility fixes.
Security News
Popular npm packages like eslint-config-prettier were compromised after a phishing attack stole a maintainer’s token, spreading malicious updates.
Security News
/Research
A phishing attack targeted developers using a typosquatted npm domain (npnjs.com) to steal credentials via fake login pages - watch out for similar scams.