Skip to content

Commit f737f49

Browse files
committed
Raise an error if the user doesn't define a _db fixture
1 parent c460aa1 commit f737f49

File tree

5 files changed

+95
-4
lines changed

5 files changed

+95
-4
lines changed

README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ mocked-engines=database.engine
8787
# In database.py
8888

8989
db = flask_sqlalchemy.SQLAlchemy()
90-
engine = sqlalchemy.create_engine('db_connection_string')
90+
engine = sqlalchemy.create_engine('DATABASE_URI')
9191
```
9292

9393
```python
@@ -489,7 +489,9 @@ Next, install a development version of the plugin:
489489
pip install -e .
490490
```
491491

492-
Export a database connection string that the tests can use:
492+
Export a [database connection string](http://docs.sqlalchemy.org/en/latest/core/engines.html#database-urls)
493+
that the tests can use (the database referenced by the string will be created
494+
during test setup, so it does not need to exist):
493495

494496
```
495497
export TEST_DATABASE_URL=<db_connection_string>

tests/test_configs.py

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,3 +59,77 @@ def test_mocked_sessionmakers(db_session):
5959

6060
result = db_testdir.runpytest()
6161
result.assert_outcomes(passed=1)
62+
63+
64+
def test_missing_db_fixture(testdir):
65+
'''
66+
Test that in the case where the user neglects to define a _db fixture, any
67+
tests requiring transactional context will raise an error.
68+
'''
69+
# Create a conftest file that is missing a _db fixture but is otherwise
70+
# valid for a Flask-SQLAlchemy test suite
71+
conftest = """
72+
import os
73+
74+
import pytest
75+
import sqlalchemy as sa
76+
from flask import Flask
77+
from flask_sqlalchemy import SQLAlchemy
78+
from pytest_postgresql.factories import (init_postgresql_database,
79+
drop_postgresql_database)
80+
81+
# Retrieve a database connection string from the shell environment
82+
try:
83+
DB_CONN = os.environ['TEST_DATABASE_URL']
84+
except KeyError:
85+
raise KeyError('TEST_DATABASE_URL not found. You must export a database ' +
86+
'connection string to the environmental variable ' +
87+
'TEST_DATABASE_URL in order to run tests.')
88+
else:
89+
DB_OPTS = sa.engine.url.make_url(DB_CONN).translate_connect_args()
90+
91+
pytest_plugins = ['pytest-flask-sqlalchemy-transactions']
92+
93+
94+
@pytest.fixture(scope='session')
95+
def database(request):
96+
'''
97+
Create a Postgres database for the tests, and drop it when the tests are done.
98+
'''
99+
pg_host = DB_OPTS.get("host")
100+
pg_port = DB_OPTS.get("port")
101+
pg_user = DB_OPTS.get("username")
102+
pg_db = DB_OPTS["database"]
103+
104+
init_postgresql_database(pg_user, pg_host, pg_port, pg_db)
105+
106+
@request.addfinalizer
107+
def drop_database():
108+
drop_postgresql_database(pg_user, pg_host, pg_port, pg_db, 9.6)
109+
110+
111+
@pytest.fixture(scope='session')
112+
def app(database):
113+
'''
114+
Create a Flask app context for the tests.
115+
'''
116+
app = Flask(__name__)
117+
118+
app.config['SQLALCHEMY_DATABASE_URI'] = DB_CONN
119+
120+
return app
121+
"""
122+
123+
testdir.makeconftest(conftest)
124+
125+
# Define a test that will always pass, assuming that fixture setup works
126+
testdir.makepyfile("""
127+
def test_missing_db_fixture(db_session):
128+
assert True
129+
""")
130+
131+
result = testdir.runpytest()
132+
result.assert_outcomes(error=1)
133+
result.stdout.fnmatch_lines([
134+
'*NotImplementedError: _db fixture not defined*'
135+
])

transactions/fixtures.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,22 @@
55
import sqlalchemy as sa
66

77

8+
@pytest.fixture(scope='module')
9+
def _db():
10+
'''
11+
A user-defined _db fixture is required to provide the plugin with a SQLAlchemy
12+
Session object that can access the test database. If the user hasn't defined
13+
that fixture, raise an error.
14+
'''
15+
msg = ("_db fixture not defined. The pytest-flask-sqlalchemy-transactions plugin " +
16+
"requires you to define a _db fixture that returns a SQLAlchemy session " +
17+
"with access to your test database. For more information, see the plugin " +
18+
"documentation: " +
19+
"https://github.com/jeancochrane/pytest-flask-sqlalchemy-transactions#conftest-setup")
20+
21+
raise NotImplementedError(msg)
22+
23+
824
@pytest.fixture(scope='function')
925
def _transaction(request, _db, mocker):
1026
'''

transactions/hooks.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,4 +9,3 @@ def pytest_collection_modifyitems(items):
99
for item in items:
1010
if item.get_marker('transactional'):
1111
item.fixturenames.append('db_session')
12-

transactions/plugin.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
from .fixtures import _transaction, _engine, _session, db_session, db_engine
1+
from .fixtures import _db, _transaction, _engine, _session, db_session, db_engine
22
from .hooks import pytest_collection_modifyitems
33

44
def pytest_addoption(parser):

0 commit comments

Comments
 (0)