Run a real Postgres database locally on Linux, OSX or Windows as part of another Go application or test.
When testing this provides a higher level of confidence than using any in memory alternative. It also requires no other external dependencies outside of the Go build ecosystem.
Heavily inspired by Java projects zonkyio/embedded-postgres and opentable/otj-pg-embedded and reliant on the great work being done by zonkyio/embedded-postgres-binaries in order to fetch precompiled binaries from Maven.
embedded-postgres uses Go modules and as such can be referenced by release version for use as a library. Use the following to add the latest release to your project.
go get -u github.com/fergusstrange/embedded-postgres
This library aims to require as little configuration as possible, favouring overridable defaults
Configuration | Default Value |
---|---|
Username | postgres |
Password | postgres |
Database | postgres |
Version | 15.3.0 |
Encoding | UTF8 |
Locale | C |
Version | 15.3.0 |
CachePath | $USER_HOME/.embedded-postgres-go/ |
RuntimePath | $USER_HOME/.embedded-postgres-go/extracted |
DataPath | $USER_HOME/.embedded-postgres-go/extracted/data |
BinariesPath | $USER_HOME/.embedded-postgres-go/extracted |
BinaryRepositoryURL | https://repo1.maven.org/maven2 |
Port | 5432 |
StartTimeout | 15 Seconds |
StartParameters | map[string]string{"max_connections": "101"} |
The RuntimePath directory is erased and recreated at each Start()
and therefore not suitable for persistent data.
If a persistent data location is required, set DataPath to a directory outside RuntimePath.
If the RuntimePath directory is empty or already initialized but with an incompatible postgres version, it will be removed and Postgres reinitialized.
Postgres binaries will be downloaded and placed in BinaryPath if BinaryPath/bin
doesn't exist.
BinaryRepositoryURL parameter allow overriding maven repository url for Postgres binaries.
If the directory does exist, whatever binary version is placed there will be used (no version check
is done).
If your test need to run multiple different versions of Postgres for different tests, make sure
BinaryPath is a subdirectory of RuntimePath.
A single Postgres instance can be created, started and stopped as follows
postgres := embeddedpostgres.NewDatabase()
err := postgres.Start()
// Do test logic
err := postgres.Stop()
or created with custom configuration
logger := &bytes.Buffer{}
postgres := NewDatabase(DefaultConfig().
Username("beer").
Password("wine").
Database("gin").
Version(V12).
RuntimePath("/tmp").
BinaryRepositoryURL("https://repo.local/central.proxy").
Port(9876).
StartTimeout(45 * time.Second).
StartParameters(map[string]string{"max_connections": "200"}).
Logger(logger))
err := postgres.Start()
// Do test logic
err := postgres.Stop()
It should be noted that if postgres.Stop()
is not called then the child Postgres process will not be released and the
caller will block.
There are a number of realistic representations of how to use this library in examples.
View the contributing guide.