`py.test`和`__init __。py`文件

时间:2011-11-23 14:58:02

标签: python unit-testing pytest

我认为py.test在某种意义上是“独立的”,它将test_*.py文件视为“原样”,并且只导入这些文件中指定的模块,而不考虑任何周围的文件。看起来我错了。这是我与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 =======================================================
$ 

如何使py.test工作并仍然拥有__init__.py个文件?

更新

在评论中,Holger Krekel问道,父目录的名称是什么。事实证明,我可以重现上面的错误只有一个父目录名称(例如,与安装的其中一个包同名,如distutils)。见这里:

~/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 
$ 

希望这些额外信息有所帮助。

3 个答案:

答案 0 :(得分:13)

看起来py.test正在使用py._path.pyimport打开您的文件。如果目录中有__init__.py个文件,则会将您的文件视为模块,否则会打开该文件。简而言之,删除__init__.py或将测试放在项目代码之外的另一个目录中(< ---好主意)。

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

答案 1 :(得分:4)

我真的建议你将目录重命名为不称为“distutils”的东西。为什么?因为您要覆盖现有模块。 当“import distutils”或“from distutils import *”出现在脚本中时(来自另一个导入或您自己的python文件),它将更喜欢您的目录而不是系统目录。 如果之前已经加载了模块distutils,则不会加载distutils,因为该符号已存在于global()中。

重命名该目录(如测试)而不是尝试与py.text / python内部进行对抗会非常简单。

答案 2 :(得分:2)

您可以告诉pytest忽略特定文件或glob模式,如上所述here.conftest.py文件放在项目的根目录中,列出您希望pytest忽略的文件:

  

但是,许多项目都有一个不想导入的setup.py。此外,可能只有特定python版本可以导入的文件。对于这种情况,您可以通过将它们列在conftest.py文件中来动态定义要忽略的文件:

     
 # content of conftest.py
 import sys

 collect_ignore = ["setup.py"]