DjangoでUTを書く時にはPythonのunittestのサブクラスにしたdjango.test.TestCaseを用いることが出来る。
その一方で、他のUTを書くことも含めて考えると、pytestを利用したいケースも多く存在すると思われる。
Djangoでpytestを利用するにはpytest-django
というライブラリをインストールする必要がある。
pytest-djangoのセットアップ方法
pytest-djangoのdocsに書いてある手順で構築すれば良い。
- pytest-djangoをpipでinstallする
- 設定ファイルに
DJANGO_SETTINGS_MODULE
を記述する
となる。特に2番目の定数値記述が必要であり、記述しない場合、pytestでtestできない状況に陥ってしまう。 どのようなケースになるかは後述する。
ドキュメント上では以下の3ファイルでの例が掲載されている。
- pytest.ini
- tox.ini
- pyproject.toml
失敗の備忘録
pytest.ini
の時の失敗した記録。
※tox, pyprojectでも同様のような結果になると予想している。
DJANGO_SETTINGS_MODULE
を設定していない場合、具体的なファイルを指定した上でpytestを実行するとImproperlyConfigured
が発生する。
root@f6ebfa8e11c6:/djangoTaskApp/mysite# pytest tasks/tests.py =============================================================== test session starts =============================================================== platform linux -- Python 3.12.2, pytest-8.0.1, pluggy-1.4.0 rootdir: /djangoTaskApp configfile: pytest.ini plugins: cov-4.1.0, django-4.8.0, Faker-24.7.1 collected 0 items / 1 error ===================================================================== ERRORS ====================================================================== _____________________________________________________ ERROR collecting mysite/tasks/tests.py ______________________________________________________ tasks/tests.py:4: in <module> from django.contrib.auth.models import User /usr/local/lib/python3.12/site-packages/django/contrib/auth/models.py:3: in <module> from django.contrib.auth.base_user import AbstractBaseUser, BaseUserManager /usr/local/lib/python3.12/site-packages/django/contrib/auth/base_user.py:57: in <module> class AbstractBaseUser(models.Model): /usr/local/lib/python3.12/site-packages/django/db/models/base.py:129: in __new__ app_config = apps.get_containing_app_config(module) /usr/local/lib/python3.12/site-packages/django/apps/registry.py:260: in get_containing_app_config self.check_apps_ready() /usr/local/lib/python3.12/site-packages/django/apps/registry.py:137: in check_apps_ready settings.INSTALLED_APPS /usr/local/lib/python3.12/site-packages/django/conf/__init__.py:102: in __getattr__ self._setup(name) /usr/local/lib/python3.12/site-packages/django/conf/__init__.py:82: in _setup raise ImproperlyConfigured( E django.core.exceptions.ImproperlyConfigured: Requested setting INSTALLED_APPS, but settings are not configured. You must either define the environment variable DJANGO_SETTINGS_MODULE or call settings.configure() before accessing settings. ============================================================= short test summary info ============================================================= ERROR tasks/tests.py - django.core.exceptions.ImproperlyConfigured: Requested setting INSTALLED_APPS, but settings are not configured. You must either define the env... !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 1 error during collection !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! ================================================================ 1 error in 0.18s ================================================================= root@f6ebfa8e11c6:/djangoTaskApp/mysite#
こうしたケースを防ぐため、以下のように記述する必要がある。
[pytest] DJANGO_SETTINGS_MODULE = mysite.settings
他の凡ミス
設定値にクォーテーションは不要だが、Pythonの文字列の癖でつい、(ダブル)クォーテーションを付与するミスをしたケース。
なお、これはpytest.ini
またはtox.ini
で起こりうると予想している。
ドキュメントの例を見ると、pyproject.toml
ではダブルクォーテーションで囲まれているため。
[pytest] DJANGO_SETTINGS_MODULE = "mysite.settings"
この時はImportError
が発生し、Python pathを追加するように言われてしまう。
が、実際にはクォーテーションが不要だったというオチだった。
ImportError: No module named '"mysite' pytest-django found a Django project in . (it contains manage.py) and added it to the Python path. If this is wrong, add "django_find_project = false" to pytest.ini and explicitly manage your Python path.