pytest-postgresql 7.0.2__tar.gz → 8.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pytest_postgresql-7.0.2 → pytest_postgresql-8.1.0}/CHANGES.rst +91 -0
- pytest_postgresql-8.1.0/PKG-INFO +443 -0
- pytest_postgresql-8.1.0/README.rst +405 -0
- {pytest_postgresql-7.0.2 → pytest_postgresql-8.1.0}/pyproject.toml +56 -27
- {pytest_postgresql-7.0.2 → pytest_postgresql-8.1.0}/pytest_postgresql/__init__.py +1 -1
- {pytest_postgresql-7.0.2 → pytest_postgresql-8.1.0}/pytest_postgresql/config.py +14 -11
- pytest_postgresql-8.1.0/pytest_postgresql/executor.py +388 -0
- {pytest_postgresql-7.0.2 → pytest_postgresql-8.1.0}/pytest_postgresql/executor_noop.py +4 -3
- {pytest_postgresql-7.0.2 → pytest_postgresql-8.1.0}/pytest_postgresql/factories/client.py +6 -7
- {pytest_postgresql-7.0.2 → pytest_postgresql-8.1.0}/pytest_postgresql/factories/noprocess.py +42 -18
- {pytest_postgresql-7.0.2 → pytest_postgresql-8.1.0}/pytest_postgresql/factories/process.py +39 -41
- {pytest_postgresql-7.0.2 → pytest_postgresql-8.1.0}/pytest_postgresql/janitor.py +32 -33
- {pytest_postgresql-7.0.2 → pytest_postgresql-8.1.0}/pytest_postgresql/loader.py +2 -2
- {pytest_postgresql-7.0.2 → pytest_postgresql-8.1.0}/pytest_postgresql/plugin.py +4 -12
- pytest_postgresql-8.1.0/pytest_postgresql.egg-info/PKG-INFO +443 -0
- {pytest_postgresql-7.0.2 → pytest_postgresql-8.1.0}/pytest_postgresql.egg-info/SOURCES.txt +3 -1
- {pytest_postgresql-7.0.2 → pytest_postgresql-8.1.0}/pytest_postgresql.egg-info/requires.txt +1 -1
- pytest_postgresql-8.1.0/tests/test_chaining.py +101 -0
- {pytest_postgresql-7.0.2 → pytest_postgresql-8.1.0}/tests/test_config.py +1 -2
- pytest_postgresql-8.1.0/tests/test_executor.py +409 -0
- {pytest_postgresql-7.0.2 → pytest_postgresql-8.1.0}/tests/test_janitor.py +5 -15
- {pytest_postgresql-7.0.2 → pytest_postgresql-8.1.0}/tests/test_postgres_options_plugin.py +12 -15
- {pytest_postgresql-7.0.2 → pytest_postgresql-8.1.0}/tests/test_postgresql.py +3 -11
- pytest_postgresql-8.1.0/tests/test_windows_compatibility.py +898 -0
- pytest_postgresql-7.0.2/PKG-INFO +0 -559
- pytest_postgresql-7.0.2/README.rst +0 -521
- pytest_postgresql-7.0.2/pytest_postgresql/executor.py +0 -240
- pytest_postgresql-7.0.2/pytest_postgresql.egg-info/PKG-INFO +0 -559
- pytest_postgresql-7.0.2/tests/test_executor.py +0 -176
- {pytest_postgresql-7.0.2 → pytest_postgresql-8.1.0}/AUTHORS.rst +0 -0
- {pytest_postgresql-7.0.2 → pytest_postgresql-8.1.0}/CONTRIBUTING.rst +0 -0
- {pytest_postgresql-7.0.2 → pytest_postgresql-8.1.0}/COPYING +0 -0
- {pytest_postgresql-7.0.2 → pytest_postgresql-8.1.0}/COPYING.lesser +0 -0
- {pytest_postgresql-7.0.2 → pytest_postgresql-8.1.0}/MANIFEST.in +0 -0
- {pytest_postgresql-7.0.2 → pytest_postgresql-8.1.0}/pytest_postgresql/exceptions.py +0 -0
- {pytest_postgresql-7.0.2 → pytest_postgresql-8.1.0}/pytest_postgresql/factories/__init__.py +0 -0
- {pytest_postgresql-7.0.2 → pytest_postgresql-8.1.0}/pytest_postgresql/py.typed +0 -0
- {pytest_postgresql-7.0.2 → pytest_postgresql-8.1.0}/pytest_postgresql/retry.py +0 -0
- {pytest_postgresql-7.0.2 → pytest_postgresql-8.1.0}/pytest_postgresql.egg-info/dependency_links.txt +0 -0
- {pytest_postgresql-7.0.2 → pytest_postgresql-8.1.0}/pytest_postgresql.egg-info/entry_points.txt +0 -0
- {pytest_postgresql-7.0.2 → pytest_postgresql-8.1.0}/pytest_postgresql.egg-info/top_level.txt +0 -0
- {pytest_postgresql-7.0.2 → pytest_postgresql-8.1.0}/pytest_postgresql.egg-info/zip-safe +0 -0
- {pytest_postgresql-7.0.2 → pytest_postgresql-8.1.0}/setup.cfg +0 -0
- {pytest_postgresql-7.0.2 → pytest_postgresql-8.1.0}/tests/test_loader.py +0 -0
- {pytest_postgresql-7.0.2 → pytest_postgresql-8.1.0}/tests/test_noopexecutor.py +0 -0
- {pytest_postgresql-7.0.2 → pytest_postgresql-8.1.0}/tests/test_template_database.py +0 -0
- {pytest_postgresql-7.0.2 → pytest_postgresql-8.1.0}/tests/test_version.py +0 -0
|
@@ -3,6 +3,97 @@ CHANGELOG
|
|
|
3
3
|
|
|
4
4
|
.. towncrier release notes start
|
|
5
5
|
|
|
6
|
+
pytest-postgresql 8.1.0 (2026-05-15)
|
|
7
|
+
====================================
|
|
8
|
+
|
|
9
|
+
Features
|
|
10
|
+
--------
|
|
11
|
+
|
|
12
|
+
- Add Windows support for ``PostgreSQLExecutor``, including platform-specific start/stop handling. (`#1182 <https://github.com/dbfixtures/pytest-postgresql/issues/1182>`__)
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
Documentation
|
|
16
|
+
-------------
|
|
17
|
+
|
|
18
|
+
- Make sure diagrams are using unified terminology.
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
Miscellaneus
|
|
22
|
+
------------
|
|
23
|
+
|
|
24
|
+
- Fix typos (`#1267 <https://github.com/dbfixtures/pytest-postgresql/issues/1267>`__)
|
|
25
|
+
- Add ``pytest-postgresql`` as an editable self-install in the Pipfile; remove the manual ``from pytest_postgresql.plugin import *`` import from ``tests/conftest.py`` and the ``makeconftest`` call in ``tests/test_postgres_options_plugin.py`` that re-registered the plugin and caused duplicate-plugin errors under editable install.
|
|
26
|
+
- Add coderabbitai configuration with instructions to keep an eye for newsfragments.
|
|
27
|
+
- Attempt to overcome random failure on CI on MacOS on xdist workers where test_executor_init_with_password is receiving
|
|
28
|
+
`FATAL: the database system is starting up` error message from psycopg.
|
|
29
|
+
|
|
30
|
+
That's the only test that doesn't have guards against attempting to start on the same port as other xdist worker.
|
|
31
|
+
- Fix codecov pipeline configuration.
|
|
32
|
+
- Fixes for diagram workflow.
|
|
33
|
+
- Improve reliability of Coverage reporting on CI
|
|
34
|
+
- Migrate package publishing step to trusted publishing.
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
pytest-postgresql 8.0.0 (2026-01-23)
|
|
38
|
+
====================================
|
|
39
|
+
|
|
40
|
+
Breaking changes
|
|
41
|
+
----------------
|
|
42
|
+
|
|
43
|
+
- Refactor ``DatabaseJanitor`` to use explicit template management. This includes a new ``as_template`` flag and making ``dbname`` a required parameter. (`#890 <https://github.com/dbfixtures/pytest-postgresql/issues/890>`__)
|
|
44
|
+
- Bump the minimum supported pytest version to 8.2.
|
|
45
|
+
|
|
46
|
+
The previous minimum was about two years old, and older pytest versions
|
|
47
|
+
can be flaky with fixture chaining that relies on `getfixturevalue` on
|
|
48
|
+
Python 3.12-3.13 when used alongside xdist. (`#890 <https://github.com/dbfixtures/pytest-postgresql/issues/890>`__)
|
|
49
|
+
- Support only PostgreSQL version 14 and up. (`#1250 <https://github.com/dbfixtures/pytest-postgresql/issues/1250>`__)
|
|
50
|
+
- Dropped support for Python 3.9 as it has reached End of Life
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
Bugfixes
|
|
54
|
+
--------
|
|
55
|
+
|
|
56
|
+
- Fix issue where `--postgresql-drop-test-database` was applied in process fixture.
|
|
57
|
+
|
|
58
|
+
It was already being read in client and noprocess fixtures. (`#1148 <https://github.com/dbfixtures/pytest-postgresql/issues/1148>`__)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
Documentation
|
|
62
|
+
-------------
|
|
63
|
+
|
|
64
|
+
- Add a Mermaid sequence diagram to the documentation to illustrate fixture chaining and hierarchical cloning. (`#890 <https://github.com/dbfixtures/pytest-postgresql/issues/890>`__)
|
|
65
|
+
- Improve code examples by adding types (`#1233 <https://github.com/dbfixtures/pytest-postgresql/issues/1233>`__)
|
|
66
|
+
- Add plugins' architecture diagram and display it in project's README. (`#1244 <https://github.com/dbfixtures/pytest-postgresql/issues/1244>`__)
|
|
67
|
+
- Improved README.rst:
|
|
68
|
+
- Added a "Quick Start" section with a simple example.
|
|
69
|
+
- Clarified `psycopg` 3 requirement for the plugin vs. `psycopg` 2 support for the application.
|
|
70
|
+
- Updated PostgreSQL versioning notes (>= 10).
|
|
71
|
+
- Explained the binary discovery mechanism (`pg_config` vs. fallbacks).
|
|
72
|
+
- Promoted `DatabaseJanitor` as an advanced API.
|
|
73
|
+
- Fixed broken table layouts and corrected various typos.
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
Features
|
|
77
|
+
--------
|
|
78
|
+
|
|
79
|
+
- Add ``depends_on`` parameter to ``postgresql_noproc`` factory to allow hierarchical cloning and chaining of process fixtures. (`#890 <https://github.com/dbfixtures/pytest-postgresql/issues/890>`__)
|
|
80
|
+
- Convert Config kept in TypedDict into a dataclass (`#1225 <https://github.com/dbfixtures/pytest-postgresql/issues/1225>`__)
|
|
81
|
+
- Marked support for Python 3.14
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
Miscellaneus
|
|
85
|
+
------------
|
|
86
|
+
|
|
87
|
+
- `#1127 <https://github.com/dbfixtures/pytest-postgresql/issues/1127>`__, `#1218 <https://github.com/dbfixtures/pytest-postgresql/issues/1218>`__
|
|
88
|
+
- Add new release workflow, which will allow releasing new versions directly from GitHub.
|
|
89
|
+
- Drop PostgreSQL 13 and add PostgreSQL 18 to the CI
|
|
90
|
+
- Update github-actions for actions-reuse 4.x
|
|
91
|
+
- Updates to pre-commit
|
|
92
|
+
|
|
93
|
+
Replaced black with ruff-format, Added https://github.com/fizyk/pyproject-validator,
|
|
94
|
+
Moved mypy configuration into pyproject.toml, extended line length to 120 characters.
|
|
95
|
+
|
|
96
|
+
|
|
6
97
|
7.0.2 (2025-05-17)
|
|
7
98
|
==================
|
|
8
99
|
|
|
@@ -0,0 +1,443 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: pytest-postgresql
|
|
3
|
+
Version: 8.1.0
|
|
4
|
+
Summary: Postgresql fixtures and fixture factories for Pytest.
|
|
5
|
+
Author-email: Grzegorz Śliwiński <fizyk+pypi@fizyk.dev>
|
|
6
|
+
Project-URL: Source, https://github.com/dbfixtures/pytest-postgresql
|
|
7
|
+
Project-URL: Bug Tracker, https://github.com/dbfixtures/pytest-postgresql/issues
|
|
8
|
+
Project-URL: Changelog, https://github.com/dbfixtures/pytest-postgresql/blob/v8.1.0/CHANGES.rst
|
|
9
|
+
Keywords: tests,pytest,fixture,postgresql
|
|
10
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
11
|
+
Classifier: Environment :: Web Environment
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: GNU Lesser General Public License v3 or later (LGPLv3+)
|
|
14
|
+
Classifier: Natural Language :: English
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Programming Language :: Python
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
23
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
24
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
25
|
+
Classifier: Topic :: Software Development :: Testing
|
|
26
|
+
Classifier: Framework :: Pytest
|
|
27
|
+
Requires-Python: >=3.10
|
|
28
|
+
Description-Content-Type: text/x-rst
|
|
29
|
+
License-File: COPYING
|
|
30
|
+
License-File: COPYING.lesser
|
|
31
|
+
License-File: AUTHORS.rst
|
|
32
|
+
Requires-Dist: pytest>=8.2
|
|
33
|
+
Requires-Dist: port-for>=0.7.3
|
|
34
|
+
Requires-Dist: mirakuru>=2.6.0
|
|
35
|
+
Requires-Dist: packaging
|
|
36
|
+
Requires-Dist: psycopg>=3.0.0
|
|
37
|
+
Dynamic: license-file
|
|
38
|
+
|
|
39
|
+
.. image:: https://raw.githubusercontent.com/dbfixtures/pytest-postgresql/main/logo.png
|
|
40
|
+
:width: 100px
|
|
41
|
+
:height: 100px
|
|
42
|
+
|
|
43
|
+
pytest-postgresql
|
|
44
|
+
=================
|
|
45
|
+
|
|
46
|
+
.. image:: https://img.shields.io/pypi/v/pytest-postgresql.svg
|
|
47
|
+
:target: https://pypi.python.org/pypi/pytest-postgresql/
|
|
48
|
+
:alt: Latest PyPI version
|
|
49
|
+
|
|
50
|
+
.. image:: https://img.shields.io/pypi/wheel/pytest-postgresql.svg
|
|
51
|
+
:target: https://pypi.python.org/pypi/pytest-postgresql/
|
|
52
|
+
:alt: Wheel Status
|
|
53
|
+
|
|
54
|
+
.. image:: https://img.shields.io/pypi/pyversions/pytest-postgresql.svg
|
|
55
|
+
:target: https://pypi.python.org/pypi/pytest-postgresql/
|
|
56
|
+
:alt: Supported Python Versions
|
|
57
|
+
|
|
58
|
+
.. image:: https://img.shields.io/pypi/l/pytest-postgresql.svg
|
|
59
|
+
:target: https://pypi.python.org/pypi/pytest-postgresql/
|
|
60
|
+
:alt: License
|
|
61
|
+
|
|
62
|
+
What is this?
|
|
63
|
+
=============
|
|
64
|
+
|
|
65
|
+
This is a pytest plugin that enables you to test code relying on a running PostgreSQL database.
|
|
66
|
+
It provides fixtures for managing both the PostgreSQL process and the client connections.
|
|
67
|
+
|
|
68
|
+
Quick Start
|
|
69
|
+
===========
|
|
70
|
+
|
|
71
|
+
1. **Install the plugin:**
|
|
72
|
+
|
|
73
|
+
.. code-block:: sh
|
|
74
|
+
|
|
75
|
+
pip install pytest-postgresql
|
|
76
|
+
|
|
77
|
+
You will also need to install ``psycopg`` (version 3). See `its installation instructions <https://www.psycopg.org/psycopg3/docs/basic/install.html>`_.
|
|
78
|
+
|
|
79
|
+
.. note::
|
|
80
|
+
|
|
81
|
+
While this plugin requires ``psycopg`` 3 to manage the database, your application code can still use ``psycopg`` 2.
|
|
82
|
+
|
|
83
|
+
2. **Run a test:**
|
|
84
|
+
|
|
85
|
+
Simply include the ``postgresql`` fixture in your test. It provides a connected ``psycopg.Connection`` object.
|
|
86
|
+
|
|
87
|
+
.. code-block:: python
|
|
88
|
+
|
|
89
|
+
def test_example(postgresql):
|
|
90
|
+
"""Check main postgresql fixture."""
|
|
91
|
+
with postgresql.cursor() as cur:
|
|
92
|
+
cur.execute("CREATE TABLE test (id serial PRIMARY KEY, num integer, data varchar);")
|
|
93
|
+
postgresql.commit()
|
|
94
|
+
|
|
95
|
+
How to use
|
|
96
|
+
==========
|
|
97
|
+
|
|
98
|
+
.. warning::
|
|
99
|
+
|
|
100
|
+
Tested on PostgreSQL versions >= 14. See tests for more details.
|
|
101
|
+
|
|
102
|
+
How does it work
|
|
103
|
+
----------------
|
|
104
|
+
|
|
105
|
+
.. image:: https://raw.githubusercontent.com/dbfixtures/pytest-postgresql/main/docs/images/architecture.svg
|
|
106
|
+
:alt: Project Architecture Diagram
|
|
107
|
+
:align: center
|
|
108
|
+
|
|
109
|
+
The plugin provides two main types of fixtures:
|
|
110
|
+
|
|
111
|
+
**1. Client Fixtures**
|
|
112
|
+
These provide a connection to a database for your tests.
|
|
113
|
+
|
|
114
|
+
* **postgresql** - A function-scoped fixture. It returns a connected ``psycopg.Connection``.
|
|
115
|
+
After each test, it terminates leftover connections and drops the test database to ensure isolation.
|
|
116
|
+
|
|
117
|
+
**2. Process Fixtures**
|
|
118
|
+
These manage the PostgreSQL server lifecycle.
|
|
119
|
+
|
|
120
|
+
* **postgresql_proc** - A session-scoped fixture that starts a PostgreSQL instance on its first use and stops it when all tests are finished.
|
|
121
|
+
* **postgresql_noproc** - A fixture for connecting to an already running PostgreSQL instance (e.g., in Docker or CI).
|
|
122
|
+
|
|
123
|
+
Customizing Fixtures
|
|
124
|
+
--------------------
|
|
125
|
+
|
|
126
|
+
You can create additional fixtures using factories:
|
|
127
|
+
|
|
128
|
+
.. code-block:: python
|
|
129
|
+
|
|
130
|
+
from pytest_postgresql import factories
|
|
131
|
+
|
|
132
|
+
# Create a custom process fixture
|
|
133
|
+
postgresql_my_proc = factories.postgresql_proc(
|
|
134
|
+
port=None, unixsocketdir='/var/run')
|
|
135
|
+
|
|
136
|
+
# Create a client fixture that uses the custom process
|
|
137
|
+
postgresql_my = factories.postgresql('postgresql_my_proc')
|
|
138
|
+
|
|
139
|
+
.. note::
|
|
140
|
+
|
|
141
|
+
Each process fixture can be configured independently through factory arguments.
|
|
142
|
+
|
|
143
|
+
Pre-populating the database for tests
|
|
144
|
+
-------------------------------------
|
|
145
|
+
|
|
146
|
+
If you want the database to be automatically pre-populated with your schema and data, there are two levels you can achieve it:
|
|
147
|
+
|
|
148
|
+
#. **Per test:** In a client fixture, by using an intermediary fixture.
|
|
149
|
+
#. **Per session:** In a process fixture.
|
|
150
|
+
|
|
151
|
+
The process fixture accepts a ``load`` parameter, which supports:
|
|
152
|
+
|
|
153
|
+
* **SQL file paths:** Loads and executes the SQL files.
|
|
154
|
+
* **Loading functions:** A callable or an import string (e.g., ``"path.to.module:function"``).
|
|
155
|
+
These functions receive **host**, **port**, **user**, **dbname**, and **password** and must perform the connection themselves (or use an ORM).
|
|
156
|
+
|
|
157
|
+
The process fixture pre-populates the database once per session into a **template database**. The client fixture then clones this template for each test, which significantly **speeds up your tests**.
|
|
158
|
+
|
|
159
|
+
.. code-block:: python
|
|
160
|
+
|
|
161
|
+
from pathlib import Path
|
|
162
|
+
postgresql_my_proc = factories.postgresql_proc(
|
|
163
|
+
load=[
|
|
164
|
+
Path("schemafile.sql"),
|
|
165
|
+
"import.path.to.function",
|
|
166
|
+
load_this_callable
|
|
167
|
+
]
|
|
168
|
+
)
|
|
169
|
+
|
|
170
|
+
Defining pre-population on the command line:
|
|
171
|
+
|
|
172
|
+
.. code-block:: sh
|
|
173
|
+
|
|
174
|
+
pytest --postgresql-populate-template=path/to/file.sql --postgresql-populate-template=path.to.function
|
|
175
|
+
|
|
176
|
+
Connecting to an existing PostgreSQL database
|
|
177
|
+
----------------------------------------------
|
|
178
|
+
|
|
179
|
+
To connect to an external server (e.g., running in Docker), use the ``postgresql_noproc`` fixture.
|
|
180
|
+
|
|
181
|
+
.. code-block:: python
|
|
182
|
+
|
|
183
|
+
postgresql_external = factories.postgresql('postgresql_noproc')
|
|
184
|
+
|
|
185
|
+
By default, it connects to ``127.0.0.1:5432``.
|
|
186
|
+
|
|
187
|
+
Chaining fixtures
|
|
188
|
+
-----------------
|
|
189
|
+
|
|
190
|
+
You can chain multiple ``postgresql_noproc`` fixtures to layer your data pre-population. Each fixture in the chain will create its own template database based on the previous one.
|
|
191
|
+
|
|
192
|
+
.. code-block:: python
|
|
193
|
+
|
|
194
|
+
from pytest_postgresql import factories
|
|
195
|
+
|
|
196
|
+
# 1. Start with a process or a no-process base
|
|
197
|
+
base_proc = factories.postgresql_proc(load=[load_schema])
|
|
198
|
+
|
|
199
|
+
# 2. Add a layer with some data
|
|
200
|
+
seeded_noproc = factories.postgresql_noproc(depends_on="base_proc", load=[load_data])
|
|
201
|
+
|
|
202
|
+
# 3. Add another layer with more data
|
|
203
|
+
more_seeded_noproc = factories.postgresql_noproc(depends_on="seeded_noproc", load=[load_more_data])
|
|
204
|
+
|
|
205
|
+
# 4. Use the final layer in your test
|
|
206
|
+
client = factories.postgresql("more_seeded_noproc")
|
|
207
|
+
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
.. image:: https://raw.githubusercontent.com/dbfixtures/pytest-postgresql/main/docs/images/architecture_chaining.svg
|
|
211
|
+
:alt: Fixture Chaining Diagram
|
|
212
|
+
:align: center
|
|
213
|
+
|
|
214
|
+
Configuration
|
|
215
|
+
=============
|
|
216
|
+
|
|
217
|
+
You can define settings via fixture factory arguments, command line options, or ``pytest.ini``. They are resolved in this order:
|
|
218
|
+
|
|
219
|
+
1. ``Fixture factory argument``
|
|
220
|
+
2. ``Command line option``
|
|
221
|
+
3. ``pytest.ini configuration option``
|
|
222
|
+
|
|
223
|
+
.. list-table:: Configuration options
|
|
224
|
+
:header-rows: 1
|
|
225
|
+
|
|
226
|
+
* - PostgreSQL option
|
|
227
|
+
- Fixture factory argument
|
|
228
|
+
- Command line option
|
|
229
|
+
- pytest.ini option
|
|
230
|
+
- Noop process fixture
|
|
231
|
+
- Default
|
|
232
|
+
* - Path to executable
|
|
233
|
+
- executable
|
|
234
|
+
- --postgresql-exec
|
|
235
|
+
- postgresql_exec
|
|
236
|
+
- -
|
|
237
|
+
- ``pg_config --bindir`` + ``pg_ctl``
|
|
238
|
+
* - host
|
|
239
|
+
- host
|
|
240
|
+
- --postgresql-host
|
|
241
|
+
- postgresql_host
|
|
242
|
+
- yes
|
|
243
|
+
- 127.0.0.1
|
|
244
|
+
* - port
|
|
245
|
+
- port
|
|
246
|
+
- --postgresql-port
|
|
247
|
+
- postgresql_port
|
|
248
|
+
- yes (5432)
|
|
249
|
+
- random
|
|
250
|
+
* - Port search count
|
|
251
|
+
-
|
|
252
|
+
- --postgresql-port-search-count
|
|
253
|
+
- postgresql_port_search_count
|
|
254
|
+
- -
|
|
255
|
+
- 5
|
|
256
|
+
* - postgresql user
|
|
257
|
+
- user
|
|
258
|
+
- --postgresql-user
|
|
259
|
+
- postgresql_user
|
|
260
|
+
- yes
|
|
261
|
+
- postgres
|
|
262
|
+
* - password
|
|
263
|
+
- password
|
|
264
|
+
- --postgresql-password
|
|
265
|
+
- postgresql_password
|
|
266
|
+
- yes
|
|
267
|
+
-
|
|
268
|
+
* - Starting parameters (extra pg_ctl arguments)
|
|
269
|
+
- startparams
|
|
270
|
+
- --postgresql-startparams
|
|
271
|
+
- postgresql_startparams
|
|
272
|
+
- -
|
|
273
|
+
- -w
|
|
274
|
+
* - Postgres exe extra arguments (passed via pg_ctl's -o argument)
|
|
275
|
+
- postgres_options
|
|
276
|
+
- --postgresql-postgres-options
|
|
277
|
+
- postgresql_postgres_options
|
|
278
|
+
- -
|
|
279
|
+
-
|
|
280
|
+
* - Location for unixsockets
|
|
281
|
+
- unixsocket
|
|
282
|
+
- --postgresql-unixsocketdir
|
|
283
|
+
- postgresql_unixsocketdir
|
|
284
|
+
- -
|
|
285
|
+
- $TMPDIR
|
|
286
|
+
* - Database name
|
|
287
|
+
- dbname
|
|
288
|
+
- --postgresql-dbname
|
|
289
|
+
- postgresql_dbname
|
|
290
|
+
- yes (handles xdist)
|
|
291
|
+
- test
|
|
292
|
+
* - Default Schema (load list)
|
|
293
|
+
- load
|
|
294
|
+
- --postgresql-load
|
|
295
|
+
- postgresql_load
|
|
296
|
+
- yes
|
|
297
|
+
-
|
|
298
|
+
* - PostgreSQL connection options
|
|
299
|
+
- options
|
|
300
|
+
- --postgresql-options
|
|
301
|
+
- postgresql_options
|
|
302
|
+
- yes
|
|
303
|
+
-
|
|
304
|
+
* - Drop test database on start
|
|
305
|
+
-
|
|
306
|
+
- --postgresql-drop-test-database
|
|
307
|
+
-
|
|
308
|
+
- -
|
|
309
|
+
- false
|
|
310
|
+
|
|
311
|
+
.. note::
|
|
312
|
+
|
|
313
|
+
If the ``executable`` is not provided, the plugin attempts to find it by calling ``pg_config``. If that fails, it fallbacks to a common path like ``/usr/lib/postgresql/13/bin/pg_ctl``.
|
|
314
|
+
|
|
315
|
+
Examples
|
|
316
|
+
========
|
|
317
|
+
|
|
318
|
+
Using SQLAlchemy
|
|
319
|
+
----------------
|
|
320
|
+
|
|
321
|
+
This example shows how to create an SQLAlchemy session fixture:
|
|
322
|
+
|
|
323
|
+
.. code-block:: python
|
|
324
|
+
|
|
325
|
+
from typing import Iterator
|
|
326
|
+
import pytest
|
|
327
|
+
from psycopg import Connection
|
|
328
|
+
from sqlalchemy import create_engine
|
|
329
|
+
from sqlalchemy.orm import Session, sessionmaker, scoped_session
|
|
330
|
+
from sqlalchemy.pool import NullPool
|
|
331
|
+
|
|
332
|
+
@pytest.fixture
|
|
333
|
+
def db_session(postgresql: Connection) -> Iterator[Session]:
|
|
334
|
+
"""Session for SQLAlchemy."""
|
|
335
|
+
user = postgresql.info.user
|
|
336
|
+
host = postgresql.info.host
|
|
337
|
+
port = postgresql.info.port
|
|
338
|
+
dbname = postgresql.info.dbname
|
|
339
|
+
|
|
340
|
+
connection_str = f'postgresql+psycopg://{user}:@{host}:{port}/{dbname}'
|
|
341
|
+
engine = create_engine(connection_str, echo=False, poolclass=NullPool)
|
|
342
|
+
|
|
343
|
+
# Assuming you use a Base model
|
|
344
|
+
from my_app.models import Base
|
|
345
|
+
Base.metadata.create_all(engine)
|
|
346
|
+
|
|
347
|
+
SessionLocal = scoped_session(sessionmaker(bind=engine))
|
|
348
|
+
yield SessionLocal()
|
|
349
|
+
|
|
350
|
+
SessionLocal.close()
|
|
351
|
+
Base.metadata.drop_all(engine)
|
|
352
|
+
|
|
353
|
+
Advanced Usage: DatabaseJanitor
|
|
354
|
+
-------------------------------
|
|
355
|
+
|
|
356
|
+
``DatabaseJanitor`` is an advanced API for managing database state outside of standard fixtures. It is used by projects like `Warehouse <https://github.com/pypa/warehouse>`_ (pypi.org).
|
|
357
|
+
|
|
358
|
+
.. code-block:: python
|
|
359
|
+
|
|
360
|
+
import psycopg
|
|
361
|
+
from pytest_postgresql.janitor import DatabaseJanitor
|
|
362
|
+
|
|
363
|
+
def test_manual_janitor(postgresql_proc):
|
|
364
|
+
with DatabaseJanitor(
|
|
365
|
+
user=postgresql_proc.user,
|
|
366
|
+
host=postgresql_proc.host,
|
|
367
|
+
port=postgresql_proc.port,
|
|
368
|
+
dbname="my_custom_db",
|
|
369
|
+
version=postgresql_proc.version,
|
|
370
|
+
password="secret_password",
|
|
371
|
+
):
|
|
372
|
+
with psycopg.connect(
|
|
373
|
+
dbname="my_custom_db",
|
|
374
|
+
user=postgresql_proc.user,
|
|
375
|
+
host=postgresql_proc.host,
|
|
376
|
+
port=postgresql_proc.port,
|
|
377
|
+
password="secret_password",
|
|
378
|
+
) as conn:
|
|
379
|
+
# use connection
|
|
380
|
+
pass
|
|
381
|
+
|
|
382
|
+
Connecting to PostgreSQL in Docker
|
|
383
|
+
----------------------------------
|
|
384
|
+
|
|
385
|
+
To connect to a Docker-run PostgreSQL, use the ``noproc`` fixture.
|
|
386
|
+
|
|
387
|
+
.. code-block:: sh
|
|
388
|
+
|
|
389
|
+
docker run --name some-postgres -e POSTGRES_PASSWORD=mysecret -d postgres
|
|
390
|
+
|
|
391
|
+
In your tests:
|
|
392
|
+
|
|
393
|
+
.. code-block:: python
|
|
394
|
+
|
|
395
|
+
from pytest_postgresql import factories
|
|
396
|
+
|
|
397
|
+
postgresql_in_docker = factories.postgresql_noproc()
|
|
398
|
+
postgresql = factories.postgresql("postgresql_in_docker", dbname="test")
|
|
399
|
+
|
|
400
|
+
def test_docker(postgresql):
|
|
401
|
+
with postgresql.cursor() as cur:
|
|
402
|
+
cur.execute("SELECT 1")
|
|
403
|
+
|
|
404
|
+
Run with:
|
|
405
|
+
|
|
406
|
+
.. code-block:: sh
|
|
407
|
+
|
|
408
|
+
pytest --postgresql-host=172.17.0.2 --postgresql-password=mysecret
|
|
409
|
+
|
|
410
|
+
Basic database state for all tests
|
|
411
|
+
----------------------------------
|
|
412
|
+
|
|
413
|
+
You can define a ``load`` function and pass it to your process fixture factory:
|
|
414
|
+
|
|
415
|
+
.. code-block:: python
|
|
416
|
+
|
|
417
|
+
import psycopg
|
|
418
|
+
from pytest_postgresql import factories
|
|
419
|
+
|
|
420
|
+
def load_database(**kwargs):
|
|
421
|
+
with psycopg.connect(**kwargs) as conn:
|
|
422
|
+
with conn.cursor() as cur:
|
|
423
|
+
cur.execute("CREATE TABLE stories (id serial PRIMARY KEY, name varchar);")
|
|
424
|
+
cur.execute("INSERT INTO stories (name) VALUES ('Silmarillion'), ('The Expanse');")
|
|
425
|
+
|
|
426
|
+
postgresql_proc = factories.postgresql_proc(load=[load_database])
|
|
427
|
+
postgresql = factories.postgresql("postgresql_proc")
|
|
428
|
+
|
|
429
|
+
def test_stories(postgresql):
|
|
430
|
+
with postgresql.cursor() as cur:
|
|
431
|
+
cur.execute("SELECT count(*) FROM stories")
|
|
432
|
+
assert cur.fetchone()[0] == 2
|
|
433
|
+
|
|
434
|
+
The process fixture populates the **template database** once, and the client fixture clones it for every test. This is fast, clean, and ensures no dangling transactions. This approach works with both ``postgresql_proc`` and ``postgresql_noproc``.
|
|
435
|
+
|
|
436
|
+
Release
|
|
437
|
+
=======
|
|
438
|
+
|
|
439
|
+
Install ``pipenv`` and dev dependencies, then run:
|
|
440
|
+
|
|
441
|
+
.. code-block:: sh
|
|
442
|
+
|
|
443
|
+
pipenv run tbump [NEW_VERSION]
|