### Conftest Setup Example Source: https://github.com/jeancochrane/pytest-flask-sqlalchemy/blob/master/README.md Provides an example of how to set up the necessary fixtures in conftest.py for pytest-flask-sqlalchemy. It includes fixtures for database initialization, Flask app context, and the SQLAlchemy session. ```python @pytest.fixture(scope='session') def database(request): ''' Create a Postgres database for the tests, and drop it when the tests are done. ''' pg_host = DB_OPTS.get("host") pg_port = DB_OPTS.get("port") pg_user = DB_OPTS.get("username") pg_db = DB_OPTS["database"] init_postgresql_database(pg_user, pg_host, pg_port, pg_db) @request.addfinalizer def drop_database(): drop_postgresql_database(pg_user, pg_host, pg_port, pg_db, 9.6) @pytest.fixture(scope='session') def app(database): ''' Create a Flask app context for the tests. ''' app = Flask(__name__) app.config['SQLALCHEMY_DATABASE_URI'] = DB_CONN return app @pytest.pytest.fixture(scope='session') def _db(app): ''' Provide the transactional fixtures with access to the database via a Flask-SQLAlchemy database connection. ''' db = SQLAlchemy(app=app) return db ``` -------------------------------- ### Development Setup: Install Plugin Source: https://github.com/jeancochrane/pytest-flask-sqlalchemy/blob/master/README.md Command to install a development version of the plugin, including test dependencies. ```bash pip install -e .[tests] ``` -------------------------------- ### Installation from Development Version Source: https://github.com/jeancochrane/pytest-flask-sqlalchemy/blob/master/README.md Instructions to install the plugin directly from its GitHub repository for development purposes. ```bash git clone git@github.com:jeancochrane/pytest-flask-sqlalchemy.git cd pytest-flask-sqlalchemy pip install . ``` -------------------------------- ### Development Setup: Run Tests Source: https://github.com/jeancochrane/pytest-flask-sqlalchemy/blob/master/README.md Command to execute the tests using pytest after setting up the development environment. ```bash pytest ``` -------------------------------- ### Installation via pip Source: https://github.com/jeancochrane/pytest-flask-sqlalchemy/blob/master/README.md Command to install the pytest-flask-sqlalchemy plugin using pip. ```bash pip install pytest-flask-sqlalchemy ``` -------------------------------- ### Test Configuration Example Source: https://github.com/jeancochrane/pytest-flask-sqlalchemy/blob/master/README.md An example of how to configure `mocked-engines` in a `setup.cfg` file to patch SQLAlchemy Engine instances for transactional testing. ```ini # In database.py engine = sqlalchemy.create_engine(DATABASE_URI) ``` -------------------------------- ### Alternative Conftest Setup Source: https://github.com/jeancochrane/pytest-flask-sqlalchemy/blob/master/README.md An alternative method for setting up the `_db` fixture, which directly returns an existing database fixture if one is already defined. ```python @pytest.fixture(scope='session') def database(): # Set up all your database stuff here # ... return db @pytest.fixture(scope='session') def _db(database): return database ``` -------------------------------- ### Development Setup: Set Database URL Source: https://github.com/jeancochrane/pytest-flask-sqlalchemy/blob/master/README.md Environment variable command to set the database connection string for running tests. ```bash export TEST_DATABASE_URL= ``` -------------------------------- ### Testing Methods with Mocked Database Connections Source: https://github.com/jeancochrane/pytest-flask-sqlalchemy/blob/master/README.md An example of testing a model method (`set_name`) that modifies the database. When used with the mocked configuration, the changes are isolated to the test and rolled back. ```python # In database.py db = flask_sqlalchemy.SQLAlchemy() engine = sqlalchemy.create_engine('DATABASE_URI') # In models.py class Table(db.Model): __tablename__ = 'table' id = db.Column(db.Integer, primary_key=True) name = db.Column(db.String(80)) def set_name(new_name): self.name = new_name db.session.add(self) db.session.commit() # In tests/test_set_name.py def test_set_name(db_session): row = db_session.query(Table).get(1) row.set_name('testing') assert row.name == 'testing' def test_transaction_doesnt_persist(db_session): row = db_session.query(Table).get(1) assert row.name != 'testing' ``` -------------------------------- ### Mocking Database Connections with pytest Configuration Source: https://github.com/jeancochrane/pytest-flask-sqlalchemy/blob/master/README.md Shows how to configure pytest to mock database sessions and engines using `setup.cfg`. This allows for testing methods that interact with the database without a live connection, ensuring changes are rolled back. ```ini # In setup.cfg [tool:pytest] mocked-sessions=database.db.session mocked-engines=database.engine ``` -------------------------------- ### db_engine Fixture Usage Source: https://github.com/jeancochrane/pytest-flask-sqlalchemy/blob/master/README.md Illustrates using the `db_engine` fixture to execute raw SQL queries within a test. It shows how to begin a transaction and execute SQL, with changes being rolled back. ```python def test_a_transaction_using_engine(db_engine): with db_engine.begin() as conn: row = conn.execute('''UPDATE table SET name = 'testing' WHERE id = 1''') def test_transaction_doesnt_persist(db_engine): row_name = db_engine.execute('''SELECT name FROM table WHERE id = 1''').fetchone()[0] assert row_name != 'testing' ``` -------------------------------- ### Mocking Database Engines Source: https://github.com/jeancochrane/pytest-flask-sqlalchemy/blob/master/README.md Configure the 'mocked-engines' setting in setup.cfg to specify which database engine objects should be mocked. This is useful for isolating tests from actual database connections. Multiple engines can be specified by separating their import paths with whitespace. ```ini [tool:pytest] mocked-engines=database.engine ``` ```ini [tool:pytest] mocked-engines=database.engine database.second_engine ``` -------------------------------- ### Enabling Transactional Tests with Autouse Fixture Source: https://github.com/jeancochrane/pytest-flask-sqlalchemy/blob/master/README.md Shows how to automatically enable transactional tests for all tests in a suite by using an autouse fixture that includes the `db_session` fixture. ```python # Automatically enable transactions for all tests, without importing any extra fixtures. @pytest.fixture(autouse=True) def enable_transactional_tests(db_session): pass ``` -------------------------------- ### Mocking SQLAlchemy Sessionmakers Source: https://github.com/jeancochrane/pytest-flask-sqlalchemy/blob/master/README.md Configure 'mocked-sessionmakers' in setup.cfg to patch SQLAlchemy's sessionmaker factory. This replaces them with a mocked class that returns the transactional db_session fixture, useful for pre-configured sessionmaker instances. Multiple paths are separated by whitespace. ```python # In database.py WorkerSessionmaker = sessionmaker() ``` ```ini [tool:pytest] mocked-sessionmakers=database.WorkerSessionmaker ``` ```ini [tool:pytest] mocked-sessionmakers=database.WorkerSessionmaker database.SecondWorkerSessionmaker ``` -------------------------------- ### Mocking SQLAlchemy Sessions Source: https://github.com/jeancochrane/pytest-flask-sqlalchemy/blob/master/README.md Use the 'mocked-sessions' property in setup.cfg to patch SQLAlchemy Session instances. This replaces them with the db_session fixture, ensuring database updates within tests are rolled back. Provide a whitespace-separated list of import paths for the session objects. ```python # In database.py db = SQLAlchemy() ``` ```ini # In setup.cfg [tool:pytest] mocked-sessions=database.db.session ``` ```ini # In setup.cfg [tool:pytest] mocked-sessions=database.db.session database.second_db.session ``` -------------------------------- ### db_session Fixture Usage Source: https://github.com/jeancochrane/pytest-flask-sqlalchemy/blob/master/README.md Demonstrates how to use the `db_session` fixture to query, modify, add, and commit changes to the database within a test. Changes are automatically rolled back. ```python def test_a_transaction(db_session): row = db_session.query(Table).get(1) row.name = 'testing' db_session.add(row) db_session.commit() def test_transaction_doesnt_persist(db_session): row = db_session.query(Table).get(1) assert row.name != 'testing' ``` -------------------------------- ### Transactional Tests with db_session Source: https://github.com/jeancochrane/pytest-flask-sqlalchemy/blob/master/README.md Demonstrates using the `db_session` fixture to perform database operations within a test. Changes made within the test are automatically rolled back. ```python def test_a_transaction(db_session): row = db_session.query(Table).get(1) row.name = 'testing' db_session.add(row) db_session.commit() def test_transaction_doesnt_persist(db_session): row = db_session.query(Table).get(1) assert row.name != 'testing' ``` -------------------------------- ### Transactional Tests with db_engine Source: https://github.com/jeancochrane/pytest-flask-sqlalchemy/blob/master/README.md Illustrates using the `db_engine` fixture, which mirrors SQLAlchemy's Engine API, for transactional database operations. Changes are rolled back after the test. ```python def test_a_transaction_using_engine(db_engine): with db_engine.begin() as conn: row = conn.execute('''UPDATE table SET name = 'testing' WHERE id = 1''') def test_transaction_doesnt_persist(db_engine): row_name = db_engine.execute('''SELECT name FROM table WHERE id = 1''').fetchone()[0] assert row_name != 'testing' ``` -------------------------------- ### Writing Transactional Tests Source: https://github.com/jeancochrane/pytest-flask-sqlalchemy/blob/master/README.md Tests are automatically wrapped in transactions if they import a transactional fixture like 'db_session'. Tests not importing these fixtures will not have transactions. This allows for selective transaction management to optimize test performance. ```python # This test will be wrapped in a transaction. def transactional_test(db_session): ... # This test **will not** be wrapped in a transaction, since it does not import a # transactional fixture. def non_transactional_test(): ... ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.