Reputation: 1367
I have a test class with two methods, and want to share a saved model instance between both methods.
My fixtures:
@pytest.fixture(scope='class')
def model_factory():
class ModelFactory(object):
def get(self):
x = Model(email='[email protected]',
name='test')
x.save()
return x
return ModelFactory()
@pytest.fixture(scope='class')
def model(model_factory):
m = model_factory.get()
return m
My expectation is to receive only the model
fixture on (both) my test methods and have it be the same, persisted on the database:
@pytest.mark.django_db
class TestModel(object):
def test1(self, model):
assert model.pk is not None
Model.objects.get(pk=model.pk) # Works, instance is in the db
def test2(self, model):
assert model.pk is not None # model.pk is the same as in test1
Model.objects.get(pk=model.pk) # Fails:
# *** DoesNotExist: Model matching query does not exist
I've verified using --pdb
that at the end of test1
, running Model.objects.all()
returns the single instance I created. Meanwhile, psql shows no record:
test_db=# select * from model_table;
id | ··· fields
(0 rows)
Running the Model.objects.all()
in pdb at the end of test2
returns an empty list, which is presumably right considering that the table is empty.
model
fixture is marked scope='class'
and saved? (This was my original question until I found out saving the model didn't do anything on the database)Using django 1.6.1
, pytest-django 2.9.1
, pytest 2.8.5
Thanks
Upvotes: 2
Views: 1603
Reputation: 988
Scope argument is in this case a bit misleading, however if you would write your code like this:
@pytest.fixture(scope='class')
def model_factory(db, request):
# body
then you would get an error basically saying that database fixture has to be implemented with 'function' scope.
I would like to add that this is being currently worked on and might be an killing feature in the future ;) github pull request
Upvotes: 0
Reputation: 1367
By looking at the postgres log I've found that pytest-django
by default does a ROLLBACK
after each test to keep things clean (which makes sense, as tests shouldn't depend on state possibly modified by earlier tests).
By decorating the test class with django_db(transaction=True)
I could indeed see the data commited at the end of each test from psql, which answers my first question.
Same as before, the test runner ensures no state is kept between tests, which is the answer to my second point.
Upvotes: 0
Reputation: 599450
Tests must be independent of each other. To ensure this, Django - like most frameworks - clears the db after each test. See the documentation.
Upvotes: 1