Skip to content

Repository files navigation

pyembedpg

pypiSupported Python Versionspypi downloadsBuild StatusLicenseCodacy BadgeCoverage Status

Provide a platform neutral way to run Postgres in integration tests. More info at: http://www.simulmedia.com/resources/blog/pyembedpg-simple-way-use-postgres-python-integration-tests/

Why

  • Running tests in parallel on different instances of Postgres
  • Testing on different versions can be useful (e.g., prod has another version of Postgres installed)
  • Easier to install a particular version than manually
  • Dropping databases and users all the time is painful (and cleanup might not be done properly everytime)

Features

It downloads the specified version of Postgres automatically from https://ftp.postgresql.org/pub/source/, build it and cache it in .pyembedpg so subsequent uses won't download it. You can start the Postgres server on any port in a context (using with) that will be shutdown when you exit the context.

How to use it

You can install pyembedpg with pip:

pip install pyembedpg

You can start a new postgres server as follows:

pg=PyEmbedPg('9.4.0')
# Start the database and download it and build it if it hasn't been done so alreadywithpg.start(15432) asdb:
# do your thing

or:

pg=PyEmbedPg('9.4.0')
# Start the database and download it and build it if it hasn't been done so alreadydb=pg.start(15432)
try:
# do your thingfinally:
db.shutdown()

If you don't specify the version (e.g., PyEmbedPg()), it will use the latest version found in .pyembedpg or on the FTP server if .pyembedpg is empty.

If you want to use the current Postgres version installed on the server you can do PyEmbedPg('local').

You can use it as follows:

pg=PyEmbedPg('9.4.0')
withpg.start(15432) aspostgres:
postgres.create_user('scott', 'tiger')
postgres.create_database('testdb', 'scott')
# Postgres is initialized, now run some querieswithpsycopg2.connect(database='postgres', user='scott', password='tiger', port=postgres.running_port) asconn:
withconn.cursor() ascursor:
cursor.execute('CREATE TABLE employee(name VARCHAR(32), age INT)')
cursor.execute("INSERT INTO employee VALUES ('John', 32)")
cursor.execute("INSERT INTO employee VALUES ('Mary', 22)")
cursor.execute('SELECT * FROM employee ORDER BY age')
assertcursor.fetchall() == [('Mary', 22), ('John', 32)]

or in unit tests:

importunittestimportpsycopg2frompyembedpgimportPyEmbedPgclassTestPyEmbedPgWithContext(unittest.TestCase):
defsetUp(self):
self.postgres=PyEmbedPg('9.4.0').start(15432)
deftest_simple_run(self):
self.postgres.create_user('scott', 'tiger')
self.postgres.create_database('testdb', 'scott')
# Postgres is initialized, now run some querieswithpsycopg2.connect(database='postgres', user='scott', password='tiger', port=self.postgres.running_port) asconn:
withconn.cursor() ascursor:
cursor.execute('CREATE TABLE employee(name VARCHAR(32), age INT)')
cursor.execute("INSERT INTO employee VALUES ('John', 32)")
cursor.execute("INSERT INTO employee VALUES ('Mary', 22)")
cursor.execute('SELECT * FROM employee ORDER BY age')
assertcursor.fetchall() == [('Mary', 22), ('John', 32)]
deftearDown(self):
self.postgres.shutdown()

You can also specify a list of ports to use (e.g., PyEmbedPg('9.4.0').start(range(15432, 15440))). The first available port will be used. This can be useful when you run multiple tests in parallel.

Troubleshooting

Error while building postgres

Check that gcc and readline (e.g., libreadline-dev on Debian, readline on MacOS) are installed.

Alternatives

Alternatively, there is another project testing.postgres that allows to use the current Postgres application installed on the server and initialize a new instance.

Contributors

About

A simple way to use Postgres in Python integration tests.

Resources

Stars

35 stars

Watchers

52 watching

Forks

Releases

Packages

Used by

Contributors

Languages