Archivos `py.test` y` __init __. py`

Pensé que py.test es “independiente” en el sentido de que trata test_*.py archivos de test_*.py “tal como son”, y solo importa los módulos especificados en estos archivos, sin respetar los archivos circundantes. Parece que estoy equivocado. Aquí está mi diálogo con py.test :

 $ ls __init__.py test_pytest.py $ cat __init__.py $ cat test_pytest.py def test_pytest(): assert True $ py.test test_pytest.py ========================================================= test session starts ========================================================== platform darwin -- Python 2.7.2 -- pytest-2.1.3 collected 0 items / 1 errors ================================================================ ERRORS ================================================================ ___________________________________________________ ERROR collecting test_pytest.py ____________________________________________________ /Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/py-1.4.5-py2.7.egg/py/_path/local.py:529: in pyimport > mod = __import__(modname, None, None, ['__doc__']) E ImportError: No module named test_pytest ======================================================= 1 error in 0.01 seconds ======================================================== $ rm __init__.py $ py.test test_pytest.py ========================================================= test session starts ========================================================== platform darwin -- Python 2.7.2 -- pytest-2.1.3 collected 1 items test_pytest.py . ======================================================= 1 passed in 0.01 seconds ======================================================= $ 

¿Cómo puedo hacer que py.test funcione y aún tenga mis archivos __init__.py ?

ACTUALIZAR

En los comentarios, Holger Krekel preguntó, ¿cuál es el nombre del directorio principal? Y resulta que puedo reproducir el error anterior solo con un determinado nombre de directorio principal (por ejemplo, el mismo nombre que uno de los paquetes instalados, como distutils ). Mira aquí:

 ~/test_min $ tree . └── distutils ├── __init__.py └── test_pytest.py 1 directory, 2 files ~/test_min $ cat distutils/__init__.py ~/test_min $ cat distutils/test_pytest.py def test_pytest(): assert True ~/test_min $ py.test distutils/test_pytest.py ======================== test session starts ========================= platform darwin -- Python 2.7.2 -- pytest-2.1.3 collected 0 items / 1 errors =============================== ERRORS =============================== _____________ ERROR collecting distutils/test_pytest.py ______________ /Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/py-1.4.5-py2.7.egg/py/_path/local.py:529: in pyimport > mod = __import__(modname, None, None, ['__doc__']) E ImportError: No module named test_pytest ====================== 1 error in 0.01 seconds ======================= ~/test_min $ rm distutils/__init__.py ~/test_min $ py.test distutils/test_pytest.py ======================== test session starts ========================= platform darwin -- Python 2.7.2 -- pytest-2.1.3 collected 1 items distutils/test_pytest.py . ====================== 1 passed in 0.01 seconds ====================== ~/test_min $ touch __init__.py ~/test_min $ ls __init__.py distutils ~/test_min $ touch distutils/__init__.py ~/test_min $ py.test distutils/test_pytest.py ======================== test session starts ========================= platform darwin -- Python 2.7.2 -- pytest-2.1.3 collected 1 items distutils/test_pytest.py . ====================== 1 passed in 0.02 seconds ====================== ~/test_min $ rm __init__.py ~/test_min $ py.test distutils/test_pytest.py ======================== test session starts ========================= platform darwin -- Python 2.7.2 -- pytest-2.1.3 collected 0 items / 1 errors =============================== ERRORS =============================== _____________ ERROR collecting distutils/test_pytest.py ______________ /Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/py-1.4.5-py2.7.egg/py/_path/local.py:529: in pyimport > mod = __import__(modname, None, None, ['__doc__']) E ImportError: No module named test_pytest ====================== 1 error in 0.01 seconds ======================= ~/test_min $ mv distutils foobar ~/test_min $ py.test foobar/test_pytest.py ======================== test session starts ========================= platform darwin -- Python 2.7.2 -- pytest-2.1.3 collected 1 items foobar/test_pytest.py . ====================== 1 passed in 0.01 seconds ====================== ~/test_min $ 

Espero que esta información adicional ayude.

Parece que py.test está usando py._path.pyimport para abrir tu archivo. Si hay un archivo __init__.py en el directorio, trata su archivo como un módulo, de lo contrario, lo abre. En pocas palabras, elimine __init__.py o ponga sus pruebas en otro directorio fuera del código de su proyecto (<--- buena idea).

http://doc.pylib.org/en/latest/_modules/py/_path/local.html#LocalPath.pyimport

Realmente le sugiero que cambie el nombre del directorio a algo que no se llame “distutils”. Por qué ? Porque estás anulando un módulo existente. Cuando en el script (desde otra importación o su propio archivo de Python) aparezca “importar los nombres” o “de los nombres de los nombres de importación”, preferirá su directorio en lugar del sistema. Si los distutils del módulo ya se han cargado anteriormente, sus distutils no se cargarán, porque el símbolo ya existe en global ().

Sería realmente más sencillo cambiar el nombre de ese directorio (como las pruebas) en lugar de intentar luchar con los internos de py.text / python.

Puede decirle a pytest que ignore archivos específicos o patrones globales como se describe aquí. Coloque un archivo conftest.py en el directorio raíz de su proyecto que enumera los archivos que desea que pytest ignore:

Sin embargo, muchos proyectos tendrán un setup.py que no quieren ser importados. Además, puede que los archivos solo se puedan importar con una versión específica de Python. Para tales casos, puede definir dinámicamente los archivos que se ignorarán enumerándolos en un archivo conftest.py:


  # content of conftest.py import sys collect_ignore = ["setup.py"]