Documentation
¶
Overview ¶
Package postgres gives an integration test a real, migrated, empty PostgreSQL database of its own.
Design ¶
One Postgres container is started per test binary (per image) with testcontainers-go and shared by every test in it. Migrations are applied once, into a template database; each test then gets its own database made with CREATE DATABASE ... TEMPLATE .... Copying a template is a file copy inside Postgres rather than a replay of the migration history, so the cost of setting up a test stays constant as the number of migrations grows.
Every database gets a unique name, so tests may call t.Parallel freely. The database is dropped WITH (FORCE) when the test ends, even if the test leaked connections.
Usage ¶
func TestMain(m *testing.M) {
code := m.Run()
_ = postgres.Cleanup() // optional: stop the container right away
os.Exit(code)
}
func TestSomething(t *testing.T) {
t.Parallel()
db := postgres.New(t, postgres.WithMigrationsDir("../../migrations"))
// db.DB is a *sqlx.DB and db.SQL a *sql.DB on an empty, fully
// migrated database. db.URL is its connection string, for handing
// to a subprocess or to a different driver.
var n int
if err := db.DB.Get(&n, "SELECT count(*) FROM users"); err != nil {
t.Fatal(err)
}
}
The migrations directory is required. A relative path is resolved against the working directory of the test binary, which `go test` sets to the directory of the package under test.
Migration bookkeeping table ¶
sql-migrate records applied migrations in a table. Its Go API defaults to "gorp_migrations", while its CLI reads the table name from dbconfig.yml. If the two disagree, the tests and the CLI keep separate bookkeeping and disagree about what has been applied. New therefore defaults to "migrations", the name most dbconfig.yml files use; set WithMigrationsTable to whatever the `table:` key of your dbconfig.yml says. The table is configured per migration run, so sql-migrate's global migrate.SetTable setting is neither needed nor modified.
Driver ¶
The package registers and uses github.com/lib/pq (driver name "postgres"). URL is a standard postgres:// URL, so code that prefers pgx can open it with sql.Open("pgx", db.URL) after importing github.com/jackc/pgx/v5/stdlib.
Index ¶
- Constants
- func Cleanup() error
- type ConnectionInfodeprecated
- type Option
- type Optionsdeprecated
- type TestDB
Constants ¶
const ( // DefaultImage is the Postgres image used unless WithImage says otherwise. DefaultImage = "postgres:16-alpine" // DefaultMigrationsTable is the sql-migrate bookkeeping table New uses // unless WithMigrationsTable says otherwise. DefaultMigrationsTable = "migrations" )
Variables ¶
This section is empty.
Functions ¶
Types ¶
type ConnectionInfo
deprecated
type ConnectionInfo struct {
Host string
Port string
User string
Password string
DBName string
SSLMode string
}
ConnectionInfo contains database connection details.
Deprecated: use TestDB.URL, which carries the same details.
func (ConnectionInfo) ConnectionString ¶
func (c ConnectionInfo) ConnectionString() string
ConnectionString returns a PostgreSQL connection string.
type Option ¶ added in v0.0.2
type Option func(*config)
Option configures New.
func WithImage ¶ added in v0.0.2
WithImage sets the Postgres image to run, DefaultImage by default. Tests asking for different images get different containers. The image must be Postgres 13 or newer, which DROP DATABASE ... WITH (FORCE) requires.
func WithMigrationsDir ¶ added in v0.0.2
WithMigrationsDir sets the directory of sql-migrate migrations to apply. It is required: a library cannot guess where its consumer keeps migrations. A relative path is resolved against the working directory.
func WithMigrationsTable ¶ added in v0.0.2
WithMigrationsTable sets the table sql-migrate records applied migrations in. It defaults to DefaultMigrationsTable ("migrations") and should match the `table:` key of your dbconfig.yml.
type Options
deprecated
type Options struct {
// MigrationsDir is the path to the migrations directory. Unlike New,
// NewTestDB treats an empty value as "apply no migrations".
MigrationsDir string
// MigrationsTable is the sql-migrate bookkeeping table. Empty keeps the
// historical behaviour of using sql-migrate's global setting
// ("gorp_migrations" unless migrate.SetTable was called).
MigrationsTable string
}
Options configures NewTestDB.
Deprecated: use New with WithMigrationsDir and WithMigrationsTable.
type TestDB ¶
type TestDB struct {
// DB is connected to the test's database.
DB *sqlx.DB
// SQL is the *sql.DB underlying DB, for code that does not use sqlx.
SQL *sql.DB
// URL is the connection string of the database, for handing it to a
// subprocess or opening it with a different driver.
URL string
// ConnInfo holds the same connection details as URL, split into fields.
//
// Deprecated: use URL.
ConnInfo ConnectionInfo
// contains filtered or unexported fields
}
TestDB is one test's own database.
func New ¶ added in v0.0.2
New returns an empty database with every migration applied, for the duration of the test, and registers t.Cleanup to drop it. It fails the test rather than returning an error: a test cannot carry on without its database.
func NewTestDB
deprecated
NewTestDB creates a new isolated test database with migrations applied. The caller must Close it.
It shares the container and the template databases with New, so it gets the same speed-up, but it returns an error instead of failing a test and does not register any cleanup.
Deprecated: use New, which fails the test on error and drops the database when the test ends.