-
Notifications
You must be signed in to change notification settings - Fork 344
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
pytest.mark.django_db doesn't play nice with setup_module() #53
Comments
The django_db mark is based on fixtures, I'm not sure how to communicate between fixtures and the setup_* methods. Could you use a module scoped fixture instead to achieve the same thing? I.e. something like pytestmark = pytest.mark.usefixture('test_table')
@pytest.fixture(scope='module')
def test_table(db):
do_sql('create table ...')
def test_fetch_val():
assert fetch_val('...') == 1 |
Just tried. Didn't work. I get |
Sorry, it should be usefixtures, not usefixture: |
Now I get Removing |
I also tried pytestmark = pytest.mark.django_db
@pytest.fixture(scope='module')
def test_table():
do_sql('''
create table test (
id int primary key,
tag int not null
);
insert into test values (1, 10), (2, 20);
''')
def test_fetch_val(test_table):
assert fetch_val('select min(id) from test') == 1
def test_fetch_val2(test_table):
assert fetch_val('select min(id) from test') == 1 which almost works, but second test fails somehow with |
Django and the django_db marker works the way that each test case runs in its own transaction, therefore using django_db with a module level fixture that inserts data into the database does not really make sense. What are your use case here? How come you are creating a database table "by hand" in your tests, and not with Django, but still want to use Django's test database/test database cursor? Couldn't you achieve what you are after by just constructing a plain database cursor? (The last example avoids the ScopeMismatchError, but it fails in the test instead because the transaction is rolled back after the first test, hence rolling back the test table.) |
I am trying to test a couple of low level db utilities, which use django cursor internally - https://github.com/Suor/handy/blob/master/handy/db.py#L40 And I find it will be far messier to define a model in I just want to execute some initialization code before running tests so that I have some data to play with. |
Oh, I made it work! Wrapping initialization SQL into Many thanks for all the tips you provided. |
That is a hack that looks a bit fragile to me. I would probably set up an extra app that is only used for tests with a simple model that you can then use to run those functions against. You could then easily just use Django's ORM to populate the data in your tests. It is slightly more typing and a couple of extra files, but then it should be safe for future breakages. |
If anyone else finds this issue: doing database setup in setup_function/setup_class/setup_module is not really supported or possible in any good way since pytest-django's database setup is based on fixtures. The solution is to use a fixture which properly requests the db fixture: |
@pelme
Is there any other way to handle it? |
Yes, that is a limitation of the db fixture as it is currently implemented. In PR #258 there has been some work towards making it possible to create database state that is bound by class/module/session scope. |
Even tough this issue is pretty old, I've found it useful to find the solution to a problem I was having with Below was working before @pytest.fixture(scope='module')
def user():
return User.objects.create(...)
@pytest.mark.django_db
def test_some_case(user):
pass After
The solution was to remove |
+1 For me, just switching from some initial Djano unit tests, this is a major drawback, when initializing the database for my API test cases. Actually supporting session/module database fixtures should be a basic feature. Any suggestions how to solve this? |
+1 |
Here is my test code:
And I get
DatabaseError: relation "test" does not exist
fromtest_fetch_val()
. I also getcaptured output. Looks like
setup_module()
is called before database is created.The text was updated successfully, but these errors were encountered: