dackdive's blog

新米webエンジニアによる技術ブログ。JavaScript(React), Salesforce, Python など

[GAE][django]django+pytest でImproperlyConfiguredエラー

GAE(python) + django で、フォームのテストをしていた時に発生した。
(テストには pytest を使っている)

ImproperlyConfigured: Requested setting USE_I18N, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings.

テスト対象の forms.py とそのテスト(抜粋)

# forms.py
from django import forms

class ContactForm(forms.Form):
    subject = forms.CharField(max_length=10)
# tests.py
import pytest

from forms import ContactForm


class TestContactForm(object):
    def setup_form(self, **kwargs):
        return ContactForm(**kwargs)

    @pytest.mark.parametrize(('data',), [
        (
            {
                'subject': '12345678901',
                },
        ),
    ])
    def test_forms(self, data):
        form = self.setup_form(data=data)

        assert form.is_valid()

実行結果

self = <django.conf.LazySettings object at 0x10340e310>, name = 'USE_I18N'

    def _setup(self, name=None):
        """
            Load the settings module pointed to by the environment variable. This
            is used the first time we need any settings at all, if the user has not
            previously configured the settings manually.
            """
        try:
            settings_module = os.environ[ENVIRONMENT_VARIABLE]
            if not settings_module: # If it's set but is an empty string.
                raise KeyError
        except KeyError:
            desc = ("setting %s" % name) if name else "settings"
            raise ImproperlyConfigured(
                "Requested %s, but settings are not configured. "
                "You must either define the environment variable %s "
                "or call settings.configure() before accessing settings."
>               % (desc, ENVIRONMENT_VARIABLE))
E           ImproperlyConfigured: Requested setting USE_I18N, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings.

エラーの内容から DJANGO_SETTINGS_MODULE が定義されていない?と思い
この1行を追加したらテストが通るようになった。

# tests.py
import pytest

from forms import ContactForm

# この1行を追加する
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'settings')


class TestContactForm(object):
    def setup_form(self, **kwargs):
        return ContactForm(**kwargs)

    @pytest.mark.parametrize(('data',), [
        (
            {
                'subject': '12345678901',
                },
        ),
    ])
    def test_forms(self, data):
        form = self.setup_form(data=data)

        assert form.is_valid()

ただ、すべてのテストクラスに追加するわけにはいかないので、
pytest を zc.buildout でインストールする時の initialization スクリプトで指定することにした。

[buildout]
parts =
  python-dev

[python-dev]
recipe = zc.recipe.egg
eggs =
  mock==1.0.0
  pytest
  pytest-xdist
  pytest-cache
  pytest-capturelog
  pytest-cov
  pytest-timeout
scripts =
  py.test=pytest
initialization =
  import os
  os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'settings')

buildout も含めた Google App Engine 用の初期設定ファイルはこちら。