Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

django-pytest setup_method database issue

I have the following set up on Ubuntu 14.04:

  • python 2.7.6
  • django 1.7 [though I reproduced the same behaviour with django 1.9 too]
  • pytest-django 2.8.0 [also tested with 2.9.1]
  • pytest 2.7.2 [also tested with 2.8.3]

And the following test code:

import pytest
from django.db import connection

import settings
from pollsapp.models import Question

original_db_name = settings.DATABASES["default"]["NAME"]

@pytest.mark.django_db
class TestExperiment(object):

    def setup_method(self, method):
        # it's not using the "test_" + DATABASE_NAME !
        assert connection.settings_dict["NAME"] == \ 
        settings.DATABASES["default"]["NAME"]
        Question.objects.create(question_text="How are you?")
        # this data remains in the main database
  1. Although the class is marked to use django database, the data created in the constructor arrive in the main (production) database (name taken from settings.py)

  2. Putting the django_db decorator above the setup_method does not make any difference

  3. This data created in the setup_method remain in the main database, are not rolled back as they should be and as they would be if the data creation call was made in the test_case method

  4. This behaviour happens when the test is run on its own. When running it within the test suite, the setup_method db calls fails with: Failed: Database access not allowed, use the django_db mark to enable although the decorator is clearly there (which means that this error message is not to be 100% trusted btw).

pytest is an awesome framework and django-pytest works great if database calls happen from django_db marked test case methods.

It looks like no db interaction should ever be present in special pytest methods such as setup_method, teardown_method, etc. Although the documentation doesn't say anything about it:

https://pytest-django.readthedocs.org/en/latest/database.html

I am getting this behaviour with both Django 1.7 as well as with 1.9 (latest stable).

Here is the link to the whole test module: https://github.com/zdenekmaxa/examples/blob/master/python/django-testing/tests/pytest_djangodb_only.py

like image 997
Zdenek Maxa Avatar asked Dec 04 '15 13:12

Zdenek Maxa


1 Answers

Unfortunately, setup_X methods does not play nice with pytest fixtures. pytest-django's database setup is based on pytest fixtures, and therefore it does not work.

I recommend that you make your setup_method an autouse fixture, that requests the db fixture:

@pytest.mark.django_db
class TestExperiment(object):

    @pytest.fixture(autouse=True)
    def setup_stuff(self, db):
        Question.objects.create(question_text="How are you?")

    def test_something(self):
        assert Question.objects.filter(question_text="How are you?").exists()

The error message given by pytest-django is confusing and misleading, I've opened an issue to track/fix this: https://github.com/pytest-dev/pytest-django/issues/297

like image 104
andreaspelme Avatar answered Oct 03 '22 14:10

andreaspelme