web-dev-qa-db-fra.com

Utilisation de pytest avec une couche src

pytest recommande incluant un répertoire supplémentaire pour séparer le code source dans un projet:

my_package
├── src  # <-- no __init__.py on this layer
│   └── my_package
│       ├── __init__.py
│       └── util_module
│           ├── __init__.py
│           └── utils.py
└── tests
    ├── __init__.py
    └── test_util_module
        ├── __init__.py
        └── test_utils.py

Malheureusement, ils ne disent rien1 sur la façon dont les importations dans le code de test devraient fonctionner dans un tel cas, qui fonctionnent pour mon IDE très bien dans cet exemple naïf2, mais provoque l'erreur suivante avec pytest:

my_package $ pytest

====================== test session starts ======================
platform linux -- Python 3.6.4, pytest-3.5.1, py-1.5.3, pluggy-0.6.0
rootdir: /home/user/workspace/my_package, inifile:
collected 0 items / 1 errors     

============================ ERRORS =============================
___ ERROR collecting tests/test_util_module/test_utils.py ___
ImportError while importing test module '/home/user/workspace/my_package/tests/test_util_module/test_utils.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
tests/test_util_module/test_utils.py:1: in <module>
    from test.test_module.some_file import starify
E   ModuleNotFoundError: No module named 'my_package.util_module'
!!!! Interrupted: 1 errors during collection !!!!!

Je peux résoudre le problème en modifiant l'importation du test par from src.my_package.util_module.utils import starify, mais alors mes IDE plaintes concernant la partie src étant redondante, je voudrais donc la garder à l'écart.


1: Ce n'est plus le cas. Depuis la version 3.7.3, pytest recommande l'installation modifiable également présente dans la réponse de @ hoefling en haut de son bonnes pratiques .

2: La configuration est virtualenv env -p python3.6; source env/bin/activate; pip install pytest

18
Arne

Ajuster le PYTHONPATH (comme suggéré dans les commentaires) est une possibilité pour résoudre le problème d'importation. Un autre ajoute un fichier conftest.py Vide dans le répertoire src:

$ touch src/conftest.py

et pytest ajoutera src à sys.path. C'est un moyen simple d'inciter pytest à ajouter une base de code à sys.path.

Cependant, la disposition src est généralement sélectionnée lorsque vous avez l'intention de créer une distribution, par exemple fournir un setup.py avec (dans ce cas) spécifiant explicitement le répertoire racine du package:

from setuptools import find_packages, setup


setup(
    ...
    package_dir={'': 'src'},
    packages=find_packages(where='src'),
    ...
)

et installer le package en mode développement (via python setup.py develop ou pip install --editable .) pendant que vous le développez. De cette façon, votre package my_package Est correctement intégré dans la structure des packages du site Python et il n'est pas nécessaire de jouer avec PYTHONPATH.

17
hoefling