pgtemp is a Rust library and cli tool that allows you to easily create temporary PostgreSQL servers for testing without using Docker.
The pgtemp Rust library allows you to spawn a PostgreSQL server in a temporary directory and get back a full connection URI with the host, port, username, and password.
The pgtemp cli tool allows you to even more simply make temporary connections, and works with any language: Run pgtemp and then use its connection URI when connecting to the database in your tests. pgtemp will then spawn a new postgresql process for each connection it receives and transparently proxy everything over that connection to the temporary database. Note that this means when you make multiple connections in a single test, changes made in one connection will not be visible in the other connections, unless you are using pgtemp's --single
mode.
pgtemp supports loading (and dumping, in the library) the database to/from dumpfiles via pg_dump
.
You must install both the postgresql client and server packages. On Debian/Ubuntu, they are postgresql postgresql-client
, on Fedora they are postgresql postgresql-server
, and on Arch Linux they are postgresql postgresql-libs
. Note also that Debian/Ubuntu install the standard postgres binaries into their own directory, so you must add them to your path. For an Ubuntu GitHub Actions runner, it looks like:
steps:
- name: Install postgres
run: sudo apt-get install postgresql postgresql-client
- name: Update path
run: find /usr/lib/postgresql/ -type d -name "bin" >> $GITHUB_PATH
To install the CLI tool, you must install it with the --features cli or --all-features options
cargo install pgtemp --features cli
pgtemp is a fairly simple program and there are other existing libraries like testing.postgresql for Python and pgtest for Go that all work the same way:
- Do some setup, like creating temporary directories and copy files
- Run the
initdb
program - Start the postgres server
- Wait until postgres has started
The novel idea (as far as I'm aware, although I also only found out about the above python/go libraries after coming up with the initial library idea) in pgtemp is the CLI/daemon which automatically provides connections to new temporary databases upon each connection.
$ cargo install --all-features pgtemp
# username, password, port, and database name are all configurable based on the provided connection URI
$ pgtemp postgresql://localhost:6543/mytestdb
starting pgtemp server at postgresql://postgres:password@localhost:6543/mytestdb
$ psql postgresql://postgres:password@localhost:6543/mytestdb
psql (16.1)
Type "help" for help.
postgres=#
See examples/ directory for examples:
- A python example with sqlalchemy and alembic, demonstrating usage with the pgtemp cli's normal and single modes
use pgtemp::PgTempDB;
use sqlx::postgres::PgConnection;
use sqlx::prelude::*;
#[tokio::test]
fn cool_db_test() {
let db = PgTempDB::async_new().await;
let mut conn = sqlx::postgres::PgConnection::connect(&db.connection_uri())
.await
.expect("failed to connect to temp db");
// ... do the rest of your test
// db is shut down and files cleaned up upon drop at the end of the test
}
Examples:
- A simple diesel example with axum
- A more complicated "task queue" example using triggers and LISTEN/NOTIFY with sqlx and axum
See the tests/ directory for complete library usage.