PostgreSQL testing utility. Both Python 2.7 and 3.3+ are supported.
To install testgres, run:
pip install testgres
We encourage you to use virtualenv for your testing environment.
Note: by default testgres runs
initdb,pg_ctl,psqlprovided byPATH.
There are several ways to specify a custom postgres installation:
- export
PG_CONFIGenvironment variable pointing to thepg_configexecutable; - export
PG_BINenvironment variable pointing to the directory with executable files.
Example:
export PG_BIN=$HOME/pg_10/bin
python my_tests.pyHere is an example of what you can do with testgres:
# create a node with random name, port, etcwithtestgres.get_new_node() asnode:
# run inidbnode.init()
# start PostgreSQLnode.start()
# execute a query in a default DBprint(node.execute('select 1'))
# ... node stops and its files are about to be removedThere are four API methods for runnig queries:
| Command | Description |
|---|---|
node.psql(query, ...) | Runs query via psql command and returns tuple (error code, stdout, stderr). |
node.safe_psql(query, ...) | Same as psql() except that it returns only stdout. If an error occures during the execution, an exception will be thrown. |
node.execute(query, ...) | Connects to PostgreSQL using psycopg2 or pg8000 (depends on which one is installed in your system) and returns two-dimensional array with data. |
node.connect(dbname, ...) | Returns connection wrapper (NodeConnection) capable of running several queries within a single transaction. |
The last one is the most powerful: you can use begin(isolation_level), commit() and rollback():
withnode.connect() ascon:
con.begin('serializable')
print(con.execute('select %s', 1))
con.rollback()By default, cleanup() removes all temporary files (DB files, logs etc) that were created by testgres' API methods.
If you'd like to keep logs, execute configure_testgres(node_cleanup_full=False) before running any tests.
Note: context managers (aka
with) callstop()andcleanup()automatically.
testgres supports python logging,
which means that you can aggregate logs from several nodes into one file:
importlogging# write everything to /tmp/testgres.loglogging.basicConfig(filename='/tmp/testgres.log')
# enable logging, and create two different nodestestgres.configure_testgres(enable_python_logging=True)
node1=testgres.get_new_node().init().start()
node2=testgres.get_new_node().init().start()
# execute a few queriesnode1.execute('select 1')
node2.execute('select 2')
# disable loggingtestgres.configure_testgres(enable_python_logging=False)Look at tests/test_simple.py file for a complete example of the logging
configuration.
It's quite easy to create a backup and start a new replica:
withtestgres.get_new_node('master') asmaster:
master.init().start()
# create a backupwithmaster.backup() asbackup:
# create and start a new replicareplica=backup.spawn_replica('replica').start()
# catch up with master nodereplica.catchup()
# execute a dummy queryprint(replica.execute('postgres', 'select 1'))testgres is also capable of running benchmarks using pgbench:
withtestgres.get_new_node('master') asmaster:
# start a new nodemaster.init().start()
# initialize default DB and run bench for 10 secondsres=master.pgbench_init(scale=2).pgbench_run(time=10)
print(res)It's often useful to extend default configuration provided by testgres.
testgres has default_conf() function that helps control some basic
options. The append_conf() function can be used to add custom
lines to configuration lines:
ext_conf="shared_preload_libraries = 'postgres_fdw'"# initialize a new nodewithtestgres.get_new_node().init() asmaster:
# ... do something ...# reset main config filemaster.default_conf(fsync=True,
allow_streaming=True)
# add a new config linemaster.append_conf('postgresql.conf', ext_conf)Note that default_conf() is called by init() function; both of them overwrite
the configuration file, which means that they should be called before append_conf().
Ildar Musin <i.musin(at)postgrespro.ru> Postgres Professional Ltd., Russia
Dmitry Ivanov <d.ivanov(at)postgrespro.ru> Postgres Professional Ltd., Russia
Ildus Kurbangaliev <i.kurbangaliev(at)postgrespro.ru> Postgres Professional Ltd., Russia
Yury Zhuravlev <stalkerg(at)gmail.com>