SqlAlchemy convenience stuff for pytest
This `pytest`_ plugin was generated with `Cookiecutter`_ along with `@hackebrot`_'s `cookiecutter-pytest-plugin`_ template.
- Provides basic utility fixtures to aid in testing projects with sqlalchemy
- Allows you to wrap test cases in sqlalchemy transactions much like django's TestCase class
- pytest, sqlalchemy, psycopg2 ( all installed during setup process )
You can install "pytest-sqlalchemy" via `pip`_ from `GitHub`_
$ pip install -e git+https://github.com/crowdcomms/pytest-sqlalchemy.git#egg=pytest-sqlalchemy
The plugin will create a completely new test database that lasts as long as the test session and is destroyed at the end.
You can execute each test case in an isolated transaction by including the db_session
fixture, eg:
def test_create_foo(db_session):
foo = Foo(name="bar")
db_session.add(foo)
db_session.commit()
assert db_session.query(Foo).count()
The transaction is automatically rolled back at the end of the test function giving you a clean slate for the next test.
You need to define a couple of fixtures to be able to use the plugin, this is mostly to 'patch' your existing Session and Base classes to use the testing database. This is probably the most tricky bit of the plugin as sqlalchemy usage in projects can vary somewhat
sqlalchemy_base_class
You must set this to your base class that you use for defining models in your project, eg:
# my_project/tests/conftest.py
from my_project.database import Base
@pytest.fixture(scope='session')
def sqlalchemy_base():
return Base
sqlalchemy_session_class
Use this fixture to supply your project's sqlalchemy Session factory, eg:
# my_project/database.py
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import scoped_session, sessionmaker
Base = declarative_base()
Session = scoped_session(sessionmaker())
...
# my_project/tests/conftest.py
from my_project.database import Session
@pytest.fixture(scope='session')
def sqlalchemy_session_class():
return Session
If your project uses a different way to obtain a sqlalchemy session, then you'll need to figure out some other way to configure that session to use the test database, possibly by mocking it in individual test cases.
database_url
This defaults to os.environ['DATABASE_URL']
but is designed to be overridden to supply an alternative. The plugin will attempt to connect to whatever database is specified and create another database alongside the original, prefixed with test_
test_db_prefix
If you don't like test_
as a prefix for your testing database, return something else here.
Contributions are very welcome. Tests can be run with `tox`_, please ensure the coverage at least stays the same before you submit a pull request.