Estoy siguiendo las buenas prácticas de pytest o al menos eso creo . Sin embargo, pytest no puede encontrar mi módulo. Parece que no incluye el directorio actual en su PYTHONPATH .
El archivo fuente:
def add(x, y): return x + yEl archivo de prueba:
import pytest from junk.ook import add def test_add_true(): assert add(1, 1) == 2Y la salida del shell con un entorno virtual de Python 3 llamado "p3".
p3; pwd /home/usr/tmp/junk p3; ls total 0 0 junk/ 0 tests/ p3; ls junk total 4.0K 4.0K ook.py 0 __init__.py p3; ls tests total 4.0K 4.0K test_ook.py 0 __pycache__/ p3; pytest ============================= test session starts ============================== platform linux -- Python 3.4.5, pytest-3.4.1, py-1.5.2, pluggy-0.6.0 rootdir: /home/usr/tmp/junk, inifile: collected 0 items / 1 errors ==================================== ERRORS ==================================== ______________________ ERROR collecting tests/test_ook.py ______________________ ImportError while importing test module '/home/usr/tmp/junk/tests/test_ook.py'. Hint: make sure your test modules/packages have valid Python names. Traceback: tests/test_ook.py:2: in <module> from junk.ook import add E ImportError: No module named 'junk' !!!!!!!!!!!!!!!!!!! Interrupted: 1 errors during collection !!!!!!!!!!!!!!!!!!!! =========================== 1 error in 0.08 seconds ============================ def test_add_true(): assert add(1, 1) == 2Sin embargo, ejecutar lo siguiente funciona bien.
p3; python -m pytest tests/ ============================= test session starts ============================== platform linux -- Python 3.4.5, pytest-3.4.1, py-1.5.2, pluggy-0.6.0 rootdir: /home/usr/tmp/junk, inifile: collected 1 item tests/test_ook.py . [100%] =========================== 1 passed in 0.02 seconds ===========================¿Qué estoy haciendo mal?
pythonpath Recientemente, pytest agregó un nuevo complemento principal que admite modificaciones de sys.path a través del valor de configuración de pythonpath . La solución es mucho más simple ahora y ya no requiere soluciones alternativas:
ejemplo pyproject.toml :
[tool.pytest.ini_options] pythonpath = [ "." ] ejemplo pytest.ini :
[pytest] pythonpath = . Las entradas de la ruta se calculan en relación con el rootdir, por lo tanto . agrega el directorio junk a sys.path en este caso.
También se permiten múltiples entradas de ruta: para un diseño
junk/ ├── src/ | └── lib.py ├── junk/ │ ├── __init__.py │ └── ook.py └── tests ├── test_app.py └── test_lib.pyLa configuración
[tool.pytest.ini_options] pythonpath = [ ".", "src", ]o
[pytest] pythonpath = . src agregará tanto el módulo lib como el paquete junk a sys.path , por lo que
import junk import libambos funcionarán.
Simplemente coloque un archivo conftest.py vacío en el directorio raíz del proyecto:
$ pwd /home/usr/tmp/junk $ touch conftest.pyLa estructura de su proyecto debe convertirse en:
junk ├── conftest.py ├── junk │ ├── __init__.py │ └── ook.py └── tests └── test_ook.py Qué sucede aquí: cuando pytest descubre un conftest.py , modifica sys.path para que pueda importar cosas del módulo conftest. Entonces, dado que ahora se encuentra un conftest.py vacío en rootdir, pytest se verá obligado a agregarlo a sys.path . El efecto secundario de esto es que su módulo junk se vuelve importable.
Simplemente agregue __init__.py al directorio de tests y a todos los directorios recursivamente dentro de él que contengan archivos de prueba.