Zombie Zen

Introducing postgrestest

By Ross Light

Today, I released a small library called postgrestest. It spins up an ephemeral PostgreSQL database in Go. I’ve found it quite useful for writing tests that use PostgreSQL while keeping the test hermetic and reasonably fast. In my benchmarks, starting a server takes roughly 650 milliseconds and creating a database takes roughly 20 milliseconds — a 70% improvement and 90% improvement, respectively, over a postgres Docker container in the default configuration.

You can install it with:

go get zombiezen.com/go/postgrestest

To use it in a test:

func TestApp(t *testing.T) {
	// Start up the PostgreSQL server. This can take a few seconds,
	// so better to do it once per test run.
	ctx := context.Background()
	srv, err := postgrestest.Start(ctx)
	if err != nil {
		t.Fatal(err)
	}
	t.Cleanup(srv.Cleanup)

	// Each of your subtests can have their own database:
	t.Run("Test1", func(t *testing.T) {
		db, err := srv.NewDatabase(ctx)
		if err != nil {
			t.Fatal(err)
		}
		_, err := db.Exec(`CREATE TABLE foo (id SERIAL PRIMARY KEY);`)
		if err != nil {
			t.Fatal(err)
		}
		// ...
	})

	t.Run("Test2", func(t *testing.T) {
		db, err := srv.NewDatabase(ctx)
		if err != nil {
			t.Fatal(err)
		}
		_, err := db.Exec(`CREATE TABLE foo (id SERIAL PRIMARY KEY);`)
		if err != nil {
			t.Fatal(err)
		}
		// ...
	})
}

Documentation is available on pkg.go.dev.

Hopefully you will also find this useful in your server tests! If you do, consider sponsoring me on GitHub.

EDIT 2020-08-09: Added performance measurements.

Posted at
Permalink