pytest-factoryboy
pytest-factoryboy copied to clipboard
Mark model fixtures with usefixtures('db_session')
Because I'm using pytest-flask-sqlalchemy (see #11), I feel the need to always add the db_session
fixture to every test that uses model fixtures from pytest-factoryboy. Particularly, if I try something like:
@pytest.mark.usefixtures("location") # ensures there is one location created.
def test_company_cascades(db_session, user):
"""Test users and locations are deleted when company is deleted."""
db_session.delete(user.company)
db_session.commit()
assert not db_session.query(User).all()
assert not db_session.query(Location).all()
It fails (sqlalchemy.exc.InvalidRequestError: Object '<User at 0x7fb602180160>' is already attached to session '12' (this is '13')
).
I can fix it by adding db_session to the usefixtures
call:
@pytest.mark.usefixtures("db_session", "location") # ensures there is one location created.
def test_company_cascades(db_session, user):
What I'm looking is for something like register(CompanyFactory, usefixtures='db_session')
or maybe a setting somewhere in conftest.py
You should configure @pytest.fixture(autouse=True)
on your db_session fixture.
Then it will apply to all tests on the conftest.py (or all if it is on your parent tests folder).
@pytest.fixture(scope='function', autouse=True)
def session(db):
"""Creates a new database session for a test."""
...
yield session
...
Another option, could be to define it on a class with several tests:
@@pytest.mark.usefixtures("db_session", "location") # ensures there is one location created.
class TestGroupUsingSession:
def test1(self):
...
def test2(self):
...
More info here: pytest-fixture.
However, not sure if this request is something really needed for pytest-factoryboy. Session used for writing into the database is defined at your factories using factory-boy methods. See Using factory_boy with ORMs. Which is already inherited in pytest-factoryboy.
@BorjaEst This would cause any test to create the database (which can be an expensive operation) even if the specific test actually doesn't need it.
@sirlantis I see the point, however, to link the session to the registration... would it be safe if the API you are testing also changes the db state? What if you want to share an instance between tests? Although indeed, it might be a nice feature, there are other ways to easily pass it. So I wouldn't close the issue oppen so maybe the developers work on it.
To speed up, instead of creating the db at each test, I would just create a fixture wich delivers a new session and rollback when the test is finished, that would be much more efficient than creating a new database every test!
As I mentioned, you can also scope your fixture to a folder where you place only the tests that need that session, or you use classes.
Closing this as a 2 years have passed. Feel free to ask it to be reopened if it's still an issue.