"Apps aren't loaded yet" when trying to run pytest-django
Solution 1
Out of the box, pytest
doesn't know about the Django database, even with pytest-django
installed. Never fear, though: pytest-django
makes it easy for your tests to access the Django database using its django_db pytest mark.
Give this a try:
import pytest
@pytest.mark.django_db
def test_was_published_recently_with_future_question():
time = timezone.now() + datetime.timedelta(days=30)
future_question = Question(pub_date=time)
assert future_question.was_published_recently() is False
Solution 2
I had a similar problem when invoking tests either with pytest
or python setup.py test
.
For pytest
invocation installing pytest-django
in my virtual env solved the problem.
For python setup.py install
adding pytest-django
to the tests_require
argument of setup()
solved it.
Here's the snippet of setup.py
:
TEST_REQUIREMENTS = [
'pytest',
'pytest-django',
'pylint',
'pylint_django',
'git-pylint-commit-hook',
]
setup(
name='foo',
version='0.0.1',
description='Foo package',
author='...',
author_email='...',
packages=['foo'],
install_requires=INSTALL_REQUIREMENTS,
setup_requires=SETUP_REQUIREMENTS,
tests_require=TEST_REQUIREMENTS,
)
Solution 3
According to Django: AppRegistryNotReady(), when not using manage.py
one must call django.setup()
explicitly. I verified this by running the pytest
test from a manage.py
shell:
Kurts-MacBook-Pro:mysite2 kurtpeek$ python3 manage.py shell
Python 3.6.3 (v3.6.3:2c5fed86e0, Oct 3 2017, 00:32:08)
Type 'copyright', 'credits' or 'license' for more information
IPython 6.2.1 -- An enhanced Interactive Python. Type '?' for help.
In [1]: import pytest
In [2]: pytest.main('polls/tests.py')
================================= test session starts ==================================
platform darwin -- Python 3.6.3, pytest-3.2.3, py-1.4.34, pluggy-0.4.0
rootdir: /Users/kurtpeek/Documents/Scratch/mysite2, inifile: pytest.ini
plugins: timeout-1.2.1
collected 1 item
polls/tests.py F
======================================= FAILURES =======================================
___________________ test_was_published_recently_with_future_question ___________________
def test_was_published_recently_with_future_question():
time = timezone.now() + datetime.timedelta(days=30)
future_question = Question(pub_date=time)
> assert future_question.was_published_recently() is False
E assert True is False
E + where True = <bound method Question.was_published_recently of <Question: >>()
E + where <bound method Question.was_published_recently of <Question: >> = <Question: >.was_published_recently
polls/tests.py:18: AssertionError
=================================== warnings summary ===================================
None
passing a string to pytest.main() is deprecated, pass a list of arguments instead.
-- Docs: http://doc.pytest.org/en/latest/warnings.html
========================= 1 failed, 1 warnings in 0.14 seconds =========================
Out[2]: 1
This is not really an acceptable solution, however, as the tests need to be runnable from the command line. Are there perhaps other pytest
decorators to ensure the required setup?
Solution 4
For me, setting the DJANGO_SETTINGS_MODULE as an export on the command line or in the pytest.ini solved the problem. It seems to ignore the export of that env var in conftest.py If I figure it out I will update this post.
Comments
-
Kurt Peek almost 2 years
Using the (partial) polls app from the Django tutorial as an example, I'm trying to get pytest-django to run.
Using the command
django-admin startproject mysite2
, I've created a project directory with the following structure:. ├── db.sqlite3 ├── manage.py ├── mysite2 │ ├── __init__.py │ ├── settings.py │ ├── urls.py │ └── wsgi.py ├── polls │ ├── __init__.py │ ├── admin.py │ ├── apps.py │ ├── migrations │ │ ├── 0001_initial.py │ │ └── __init__.py │ ├── models.py │ ├── tests.py │ ├── urls.py │ └── views.py └── pytest.ini
My
pytest.ini
looks like[pytest] DJANGO_SETTINGS_MODULE = mysite2.settings python_files = tests.py test_*.py *_tests.py
Following the tutorial, in
polls/models.py
I've createdQuestion
andChoice
models:import datetime from django.db import models from django.utils import timezone class Question(models.Model): question_text = models.CharField(max_length=200) pub_date = models.DateTimeField('date published') def __str__(self): return self.question_text def was_published_recently(self): return self.pub_date >= timezone.now() - datetime.timedelta(days=1) class Choice(models.Model): question = models.ForeignKey(Question, on_delete=models.CASCADE) choice_text = models.CharField(max_length=200) votes = models.IntegerField(default=0) def __str__(self): return self.choice_text
Now, if I make
tests.py
as described in the tutorial, which is based on Python's built-inunittest
module,import datetime from django.utils import timezone from django.test import TestCase from .models import Question class QuestionModelTests(TestCase): def test_was_published_recently_with_future_question(self): time = timezone.now() + datetime.timedelta(days=30) future_question = Question(pub_date=time) self.assertIs(future_question.was_published_recently(), False)
and I run
python manage.py test
from the command line, the test fails expected:Creating test database for alias 'default'... System check identified no issues (0 silenced). F ====================================================================== FAIL: test_was_published_recently_with_future_question (polls.tests.QuestionModelTests) ---------------------------------------------------------------------- Traceback (most recent call last): File "/Users/kurtpeek/Documents/Scratch/mysite2/polls/tests.py", line 23, in test_was_published_recently_with_future_question self.assertIs(future_question.was_published_recently(), False) AssertionError: True is not False ---------------------------------------------------------------------- Ran 1 test in 0.001s FAILED (failures=1) Destroying test database for alias 'default'...
However, if I change the testing code to the (attempted)
pytest
equivalent (that is, without having to subclassTestCase
and with ordinary assertions):def test_was_published_recently_with_future_question(): time = timezone.now() + datetime.timedelta(days=30) future_question = Question(pub_date=time) assert future_question.was_published_recently() is False
and run the
pytest
command, I get the following error:================================= test session starts ================================== platform darwin -- Python 3.6.3, pytest-3.2.3, py-1.4.34, pluggy-0.4.0 rootdir: /Users/kurtpeek/Documents/Scratch/mysite2, inifile: pytest.ini plugins: timeout-1.2.1 collected 0 items / 1 errors ======================================== ERRORS ======================================== ___________________________ ERROR collecting polls/tests.py ____________________________ polls/tests.py:10: in <module> from .models import Question polls/models.py:6: in <module> class Question(models.Model): /Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/db/models/base.py:100: in __new__ app_config = apps.get_containing_app_config(module) /Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/apps/registry.py:244: in get_containing_app_config self.check_apps_ready() /Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/django/apps/registry.py:127: in check_apps_ready raise AppRegistryNotReady("Apps aren't loaded yet.") E django.core.exceptions.AppRegistryNotReady: Apps aren't loaded yet. !!!!!!!!!!!!!!!!!!!!!!! Interrupted: 1 errors during collection !!!!!!!!!!!!!!!!!!!!!!!! =============================== 1 error in 0.64 seconds ================================
So far I haven't been able to find a way to fix this. Any ideas on how to get the test to run?
-
Kurt Peek over 6 yearsInteresting idea, but according to the docs, "Less boilerplate: no need to import unittest, create a subclass with methods. Just write tests as regular functions." should be one of the advantages of
pytest-django
, so the subclassing should not be necessary. -
jaywink almost 6 yearsThis should be the accepted answer imho. pytest-django is the glue that solves the problem and makes Django and pytest friends.
-
Alex Pavlenko over 5 yearsI had similar issue. To whoever stumbles upon the same error:
pip uninstall django-pytest
andpip install pytest-django
instead. -
Yunti almost 5 yearsThis worked for me . confusing how there is a django-pytest too!