4

I have a project structure like this:

setup.cfg
integration_tests/
  |----tests.py
src/
  |----manage.py
  |----my_django_app/

And a setup.cfg with this:

[tool:pytest]
addopts=--tb=short --strict -ra
DJANGO_SETTINGS_MODULE = my_django_app.settings
env = 
    APP_ENV=testing
    USE_SQLITE_DB=True

But when I navigate to the top of that directory structure and run pytest, I get the following:

"pytest-django could not find a Django project (no manage.py file could be found). You must explicitly add your Django project to the Python path to have it picked up."

If I instead navigate to /src/ and run pytest, the tests run without issue, though obviously since I am down a level none of the inegration tests run.

According to the documentation, it seems like it should drill down from where you run pytest to attempt to find a manage.py: https://pytest-django.readthedocs.io/en/latest/managing_python_path.html#automatic-looking-for-of-django-projects

If that isn't the case, then is there some way to configure a setting in setup.cfg to add src/ to the PYTHONPATH? The suggestion in the doc to install src/ in editable mode using pip isn't really tenable in our environment.

Benyamin Jafari
  • 27,880
  • 26
  • 135
  • 150
fildred13
  • 2,280
  • 8
  • 28
  • 52

1 Answers1

6

You can use pytest-pythonpaths plugin for pytests.

Example:

[pytest] 
python_paths = your/path/apps your/path/libs

In your specific case:

[tool:pytest]
addopts=--tb=short --strict -ra
DJANGO_SETTINGS_MODULE = my_django_app.settings
env = 
    APP_ENV=testing
    USE_SQLITE_DB=True
python_paths = src

Why manage.py can't be found?

First take a look at how does pytest test discovery.

Conventions for Python test discovery

pytest implements the following standard test discovery:

  • If no arguments are specified then collection starts from testpaths (if configured) or the current directory. Alternatively, command line arguments can be used in any combination of directories, file names or node ids.

  • Recurse into directories, unless they match norecursedirs. In those directories, search for test_*.py or *_test.py files, imported by their test package name.

  • From those files, collect test items: test prefixed test functions or methods outside of class test prefixed test functions or methods inside Test prefixed test classes (without an init method)

So, manage.py do not qualify as a test file hence is not discovered automatically thought, you need it in the python path in order to run your tests.

Raydel Miranda
  • 13,825
  • 3
  • 38
  • 60
  • Seems like a reasonable solution. Too bad it adds a dependency, but it's neat and gets the job done. Thanks! It doesn't really answer the question of WHY manage.py can't be found, though, and I'd be curious if anyone knows why. – fildred13 Feb 13 '19 at 15:07
  • 1
    @fildred13 I have updated the answer, I hope that helps you to understand why pytest don't find `manage.py` if not in the python path. – Raydel Miranda Mar 22 '19 at 21:22
  • 1
    Update: with pytest 7.0.0, pytest-pythonpath is incorporated (and therefore not needed extra). It is called `pythonpath` instead of `python_paths` now – felice Jun 01 '22 at 15:32