Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit0ca0f88

Browse files
Docs: refresh README and usage guidance (#291)
1 parentd049d60 commit0ca0f88

File tree

2 files changed

+212
-92
lines changed

2 files changed

+212
-92
lines changed

‎README.md‎

Lines changed: 76 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -6,204 +6,199 @@
66

77
#testgres
88

9-
PostgreSQL testing utility. Python 3.7.17+ is supported.
10-
9+
Utility for orchestrating temporary PostgreSQL clusters in Python tests. Supports Python 3.7.17 and newer.
1110

1211
##Installation
1312

14-
To install`testgres`, run:
13+
Install`testgres` from PyPI:
1514

16-
```
15+
```sh
1716
pip install testgres
1817
```
1918

20-
We encourage you to use`virtualenv` for your testing environment.
21-
19+
Use a dedicated virtual environment for isolated test dependencies.
2220

2321
##Usage
2422

2523
###Environment
2624

27-
>Note: by default testgres runs`initdb`,`pg_ctl`,`psql`provided by`PATH`.
25+
>Note: by default`testgres` invokes`initdb`,`pg_ctl`,and`psql`binaries found in`PATH`.
2826
29-
There are several ways to specify a custom postgres installation:
27+
Specify a custom PostgreSQL installation in one of the following ways:
3028

31-
* export`PG_CONFIG` environment variablepointingto the`pg_config` executable;
32-
* export`PG_BIN` environment variablepointingto the directory withexecutable files.
29+
- Set the`PG_CONFIG` environment variableto pointto the`pg_config` executable.
30+
- Set the`PG_BIN` environment variableto pointto the directory withPostgreSQL binaries.
3331

3432
Example:
3533

36-
```bash
37-
export PG_BIN=$HOME/pg_10/bin
34+
```sh
35+
export PG_BIN=$HOME/pg_16/bin
3836
python my_tests.py
3937
```
4038

41-
4239
###Examples
4340

44-
Here is an example of what you can do with`testgres`:
41+
Create a temporary node, run queries, and let`testgres` clean up automatically:
4542

4643
```python
47-
# create a node with random name, port,etc
44+
# create a node witharandom name, port,and data directory
4845
with testgres.get_new_node()as node:
4946

50-
# runinidb
47+
# runinitdb
5148
node.init()
5249

5350
# start PostgreSQL
5451
node.start()
5552

56-
# execute a query ina defaultDB
53+
# execute a query inthe defaultdatabase
5754
print(node.execute('select 1'))
5855

59-
#... nodestopsand its files areabout to beremoved
56+
#the nodeis stoppedand its files are removed automatically
6057
```
6158

62-
There are four API methods for running queries:
59+
###Query helpers
60+
61+
`testgres` provides four helpers for executing queries against the node:
6362

6463
| Command| Description|
65-
|----------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------|
66-
|`node.psql(query, ...)`| Runs query via`psql` command and returns tuple`(error code, stdout, stderr)`.|
67-
|`node.safe_psql(query, ...)`| Same as`psql()` except that it returns only`stdout`. If an error occurs during the execution, an exception will be thrown.|
68-
|`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.|
69-
|`node.connect(dbname, ...)`| Returns connection wrapper (`NodeConnection`) capable of running several queries within a single transaction.|
64+
|---------|-------------|
65+
|`node.psql(query, ...)`| Runs the query via`psql` and returns a tuple`(returncode, stdout, stderr)`.|
66+
|`node.safe_psql(query, ...)`| Same as`psql()` but returns only`stdout` and raises if the command fails.|
67+
|`node.execute(query, ...)`| Connects via`psycopg2` or`pg8000` (whichever is available) and returns a list of tuples.|
68+
|`node.connect(dbname, ...)`| Returns a`NodeConnection` wrapper for executing multiple statements within a transaction.|
69+
70+
Example of transactional usage:
7071

71-
The last one is the most powerful: you can use`begin(isolation_level)`,`commit()` and`rollback()`:
7272
```python
7373
with node.connect()as con:
7474
con.begin('serializable')
7575
print(con.execute('select%s',1))
7676
con.rollback()
7777
```
7878

79-
8079
###Logging
8180

82-
By default,`cleanup()` removes all temporary files (DB files, logs etc) that were created by testgres' API methods.
83-
If you'd like to keep logs, execute`configure_testgres(node_cleanup_full=False)` before running any tests.
81+
By default`cleanup()` removes all temporary files (data directories, logs, and so on) created by the API. Call`configure_testgres(node_cleanup_full=False)` before starting nodes if you want to keep logs for inspection.
8482

85-
>Note: context managers (aka`with`) call`stop()` and`cleanup()` automatically.
83+
>Note: context managers (the`with` statement) call`stop()` and`cleanup()` automatically.
8684
87-
`testgres` supports[python logging](https://docs.python.org/3.6/library/logging.html),
88-
which means that you can aggregate logs from several nodes into one file:
85+
`testgres` integrates with the standard[Python logging](https://docs.python.org/3/library/logging.html) module, so you can aggregate logs from multiple nodes:
8986

9087
```python
9188
import logging
9289

9390
# write everything to /tmp/testgres.log
9491
logging.basicConfig(filename='/tmp/testgres.log')
9592

96-
# enable logging, and create two different nodes
93+
# enable logging and create two nodes
9794
testgres.configure_testgres(use_python_logging=True)
9895
node1= testgres.get_new_node().init().start()
9996
node2= testgres.get_new_node().init().start()
10097

101-
# execute a few queries
10298
node1.execute('select 1')
10399
node2.execute('select 2')
104100

105101
# disable logging
106102
testgres.configure_testgres(use_python_logging=False)
107103
```
108104

109-
Look at`tests/test_simple.py` file for a complete example of the logging
110-
configuration.
111-
105+
See`tests/test_simple.py` for a complete logging example.
112106

113-
###Backup& replication
107+
###Backupand replication
114108

115-
It's quite easy to create a backupandstart a new replica:
109+
Creating backupsandspawning replicas is straightforward:
116110

117111
```python
118112
with testgres.get_new_node('master')as master:
119113
master.init().start()
120114

121-
# create a backup
122115
with master.backup()as backup:
123-
124-
# create and start a new replica
125116
replica= backup.spawn_replica('replica').start()
126-
127-
# catch up with master node
128117
replica.catchup()
129118

130-
# execute a dummy query
131119
print(replica.execute('postgres','select 1'))
132120
```
133121

134122
###Benchmarks
135123

136-
`testgres` is also capable of running benchmarks using`pgbench`:
124+
Use`pgbench` through`testgres` to run quick benchmarks:
137125

138126
```python
139127
with testgres.get_new_node('master')as master:
140-
# start a new node
141128
master.init().start()
142129

143-
# initialize default DB and run bench for 10 seconds
144-
res= master.pgbench_init(scale=2).pgbench_run(time=10)
145-
print(res)
130+
result= master.pgbench_init(scale=2).pgbench_run(time=10)
131+
print(result)
146132
```
147133

148-
149134
###Custom configuration
150135

151-
It's often useful to extend default configuration provided by`testgres`.
152-
153-
`testgres` has`default_conf()` function that helps control some basic
154-
options. The`append_conf()` function can be used to add custom
155-
lines to configuration lines:
136+
`testgres` ships with sensible defaults. Adjust them as needed with`default_conf()` and`append_conf()`:
156137

157138
```python
158-
ext_conf="shared_preload_libraries = 'postgres_fdw'"
139+
extra_conf="shared_preload_libraries = 'postgres_fdw'"
159140

160-
# initialize a new node
161141
with testgres.get_new_node().init()as master:
162-
163-
# ... do something ...
164-
165-
# reset main config file
166-
master.default_conf(fsync=True,
167-
allow_streaming=True)
168-
169-
# add a new config line
170-
master.append_conf('postgresql.conf', ext_conf)
142+
master.default_conf(fsync=True,allow_streaming=True)
143+
master.append_conf('postgresql.conf', extra_conf)
171144
```
172145

173-
Note that`default_conf()` is called by`init()` function; both of them overwrite
174-
the configuration file, which means that they should be called before`append_conf()`.
146+
`default_conf()` is called by`init()` and rewrites the configuration file. Apply`append_conf()` afterwards to keep custom lines.
175147

176148
###Remote mode
177-
Testgres supports the creation of PostgreSQL nodes on a remote host. This is useful when you want to run distributed tests involving multiple nodes spread across different machines.
178149

179-
To use this feature, you need to use the RemoteOperations class. This feature is only supported with Linux.
180-
Here is an example of how you might set this up:
150+
You can provision nodes on a remote host (Linux only) by wiring`RemoteOperations` into the configuration:
181151

182152
```python
183153
from testgresimport ConnectionParams, RemoteOperations, TestgresConfig, get_remote_node
184154

185-
# Set up connection params
186155
conn_params= ConnectionParams(
187-
host='your_host',# replace with your host
188-
username='user_name',# replace with your username
189-
ssh_key='path_to_ssh_key'# replace with your SSH keypath
156+
host='example.com',
157+
username='postgres',
158+
ssh_key='/path/to/ssh/key'
190159
)
191160
os_ops= RemoteOperations(conn_params)
192161

193-
# Add remote testgres config before test
194162
TestgresConfig.set_os_ops(os_ops=os_ops)
195163

196-
# Proceed with your test
197-
deftest_basic_query(self):
164+
deftest_basic_query():
198165
with get_remote_node(conn_params=conn_params)as node:
199166
node.init().start()
200-
res= node.execute('SELECT 1')
201-
self.assertEqual(res, [(1,)])
167+
assert node.execute('SELECT 1')== [(1,)]
202168
```
203169

170+
###Pytest integration
171+
172+
Use fixtures to create and clean up nodes automatically when testing with`pytest`:
173+
174+
```python
175+
import pytest
176+
import testgres
177+
178+
@pytest.fixture
179+
defpg_node():
180+
node= testgres.get_new_node().init().start()
181+
try:
182+
yield node
183+
finally:
184+
node.stop()
185+
node.cleanup()
186+
187+
deftest_simple(pg_node):
188+
assert pg_node.execute('select 1')[0][0]==1
189+
```
190+
191+
This pattern keeps tests concise and ensures that every node is stopped and removed even if the test fails.
192+
193+
###Scaling tips
194+
195+
- Run tests in parallel with`pytest -n auto` (requires`pytest-xdist`). Ensure each node uses a distinct port by setting`PGPORT` in the fixture or by passing the`port` argument to`get_new_node()`.
196+
- Always call`node.cleanup()` after each test, or rely on context managers/fixtures that do it for you, to avoid leftover data directories.
197+
- Prefer`node.safe_psql()` for lightweight assertions that should fail fast; use`node.execute()` when you need structured Python results.
198+
204199
##Authors
205200

206201
[Ildar Musin](https://github.com/zilder)
207202
[Dmitry Ivanov](https://github.com/funbringer)
208203
[Ildus Kurbangaliev](https://github.com/ildus)
209-
[Yury Zhuravlev](https://github.com/stalkerg)
204+
[Yury Zhuravlev](https://github.com/stalkerg)

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp