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.pyBy 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:
import logging
# write everything to /tmp/testgres.log
logging.basicConfig(filename='/tmp/testgres.log')
# create two different nodes with logging
node1 = testgres.get_new_node(use_logging=True).init().start()
node2 = testgres.get_new_node(use_logging=True).init().start()
# execute a few queries
node1.execute('postgres', 'select 1')
node2.execute('postgres', 'select 2')Here is an example of what you can do with testgres:
with testgres.get_new_node('test') as node:
    node.init()  # run initdb
    node.start() # start PostgreSQL
    print(node.execute('postgres', 'select 1'))
    node.stop()  # stop PostgreSQLLet's walk through the code. First, you create a new node using:
with testgres.get_new_node('master') as node:or
with testgres.get_new_node('master', '/path/to/DB') as node:where master is a node's application name. Name matters if you're testing something like replication.
Function get_new_node() only creates directory structure in specified directory (or somewhere in '/tmp' if
we did not specify base directory) for cluster. After that, we have to initialize the PostgreSQL cluster:
node.init()This function runs initdb command and adds some basic configuration to postgresql.conf and pg_hba.conf files.
Function init() accepts optional parameter allows_streaming which configures cluster for streaming replication (default is False).
Now we are ready to start:
node.start()Finally, our temporary cluster is able to process queries. There are four ways to run them:
| Command | Description | 
|---|---|
| node.psql(dbname, query) | Runs query via psqlcommand and returns tuple(error code, stdout, stderr). | 
| node.safe_psql(dbname, query) | Same as psql()except that it returns onlystdout. If an error occures during the execution, an exception will be thrown. | 
| node.execute(dbname, query) | Connects to PostgreSQL using psycopg2orpg8000(depends on which one is installed in your system) and returns two-dimensional array with data. | 
| node.connect(dbname, username) | 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():
with node.connect() as con:
    con.begin('serializable')
    print(con.execute('select %s', 1))
    con.rollback()To stop the server, run:
node.stop()It's quite easy to create a backup and start a new replica:
with testgres.get_new_node('master') as master:
    master.init().start()
    with master.backup() as backup:
        # create and start a new replica
        replica = backup.spawn_replica('replica').start()
        # catch up with master node
        replica.catchup()
        # execute a dummy query
        print(replica.execute('postgres', 'select 1'))testgres also can help you to make benchmarks using pgbench from postgres installation:
with testgres.get_new_node('master') as master:
    # start a new node
    master.init().start()
    # initialize default database for TPC-B
    master.pgbench_run(options=['-i'])
    # run benchmark for 20 seconds and show results
    print(master.pgbench_run(options=['-T', '20']))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>