pythonpython-3.xdjangopytestpytest-django

pytest-django cannot find my existing module


to give a bit of context, I'm learning test unit in django and made an overly simple app to get started (Here is the structure of my project).

Here is my problem:
When launching my unit tests on my django app, I get a ModuleNotFoundError event though the module exists.

Sample of code:

from django.shortcuts import get_object_or_404, render
from .models import Book


def book_infos(request, pk):
    book = get_object_or_404(Book, pk=pk)
    return render(request, "book_infos.html", {'book': book})

And the test associated:

import pytest
from django.urls import reverse
from django.test import Client
from django_pytest.library.models import Book
from pytest_django.asserts import assertTemplateUsed


@pytest.mark.django_db
def test_book_infos_view():
    client = Client()
    Book.objects.create(author="Jules Verne",
                        title="20 milles lieues sous les mers")
    path = reverse('infos', kwargs={'pk': 1})
    response = client.get(path)
    content = response.content.decode()
    expected_content = "<p>Jules Verne | 20 milles lieues sous les mers</p>"

    assert content == expected_content
    assert response.status_code == 200
    assertTemplateUsed(response, "book_infos.html")

My pytest.ini is as follow

[pytest]
pythonpath = . library tests
DJANGO_SETTINGS_MODULE = django_pytest.settings
python_files = test_*.py

When I run pytest tests/library/test_views.py from django-pytest I get this result:

platform win32 -- Python 3.11.5, pytest-7.4.3, pluggy-1.3.0                                                     
django: version: 4.2.7, settings: django_pytest.settings (from ini)                                             
rootdir: ...\django-pytest\django_pytest
configfile: pytest.ini                                                                                          
plugins: django-4.6.0

_ ERROR collecting tests/library/test_views.py _

ImportError while importing test module '...\django-pytest\django_pytest\tests\library\test_views.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
C:\Python311\Lib\importlib\__init__.py:126: in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
E   ModuleNotFoundError: No module named 'django_pytest.tests'

The same test run in debug I get this:

ERROR: not found: ...\django-pytest\django_pytest\tests\library\test_views.py::test_book_infos_view
(no name '...\\django-pytest\\django_pytest\\tests\\library\\test_views.py::test_book_infos_view' in any of [<Module test_views.py>])

tests/library/test_views.py:None (tests/library/test_views.py)
ImportError while importing test module '...\django-pytest\django_pytest\tests\library\test_views.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
..\..\..\venv\Lib\site-packages\_pytest\python.py:617: in _importtestmodule
    mod = import_path(self.path, mode=importmode, root=self.config.rootpath)
..\..\..\venv\Lib\site-packages\_pytest\pathlib.py:567: in import_path
    importlib.import_module(module_name)
C:\Python311\Lib\importlib\__init__.py:126: in import_module
    return _bootstrap._gcd_import(name[level:], package, level)

E   ModuleNotFoundError: No module named 'django_pytest.tests'

What I tried:
I checked the pytest/pytest-django compatibility.
I added pythonpath = . library tests to the pytest.ini following this.
I tried launching py -m pytest from django-pytest instead of django-pytest/django_pytest but got the following ERROR django_pytest/tests/library/test_views.py - 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 accessin...
I tried changing project structure (moving test in library module).

Would anyone have an idea why this error shows ?

Thank you!

Stack :

Python==3.11
Django==4.2.7
pytest==7.4.3
pytest-django==4.6.0

(All packages installed in venv)


Solution

  • Managed to make it work :

    django-pytest
    \_ django_pytest
      \_ django_pytest
      |_ library
      |_ tests
      |_ __init__.py
      |_ manage.py
    

    to

    django-pytest
    \_ project_tets
      \_ django_pytest
      |_ library
      |_ tests
      |_ __init__.py
      |_ manage.py
    
    from project_test.library.models import Book
    

    to

    from library.models import Book
    

    These modifications don't seem much to me and I don't understand why they solved my problem.

    Django create the structure of 2 packages with the same name, so I guess I'll have to systematicaly rename the parent one for pytest-django to work.

    And bear with these linted import X)