简体   繁体   English

`py.test` 和 `__init__.py` 文件

[英]`py.test` and `__init__.py` files

I thought py.test is "standalone" in a sense that it treats test_*.py files "as it is", and only imports modules specified in these files, with no respect to any surrounding files.我认为py.test是“独立的”,因为它“按py.test ”处理test_*.py文件,并且只导入这些文件中指定的模块,而不考虑任何周围的文件。 It looks like I'm wrong.看来我错了。 Here is my dialog with py.test :这是我与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 =======================================================
$ 

How do I make py.test work and still have my __init__.py files?如何使py.test工作并仍然保留我的__init__.py文件?

UPDATE更新

In comments, Holger Krekel asked, what is the name of parent directory.在评论中,Holger Krekel 问,父目录的名称是什么。 And it turns out that I can reproduce the error above only having a certain parent directory name (eg the same name as one of the packages installed, like distutils ).事实证明,我只能通过某个父目录名称(例如,与安装的软件包之一同名,如distutils )才能重现上述错误。 See here:看这里:

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

Hope this additional information will help.希望这些额外的信息会有所帮助。

Looks like py.test is using py._path.pyimport to open your file.看起来 py.test 正在使用py._path.pyimport打开您的文件。 If there is a __init__.py file in the directory, it treats your file as a module, otherwise it opens the file.如果目录中有__init__.py文件,它会将您的文件视为一个模块,否则它会打开该文件。 Long story short, delete the __init__.py or put your tests in another directory outside your project code (<--- good idea).长话短说,删除__init__.py或将您的测试放在项目代码之外的另一个目录中(<--- 好主意)。

https://py.readthedocs.io/en/latest/path.html#py._path.local.LocalPath.pyimport https://py.readthedocs.io/en/latest/path.html#py._path.local.LocalPath.pyimport

I really suggest you to rename the directory to something not called "distutils".我真的建议您将目录重命名为不称为“distutils”的名称。 Why ?为什么 ? Because you are overriding an existing module.因为您正在覆盖现有模块。 When "import distutils" or "from distutils import *" appear in the script (from another import or your own python file), it will prefer your directory instead the system one.当“import distutils”或“from distutils import *”出现在脚本中时(来自另一个导入或你自己的python文件),它会更喜欢你的目录而不是系统目录。 If the module distutils have been already loaded before, your distutils will not be loaded, because the symbol already exists in global().如果之前已经加载了模块 distutils,则不会加载您的 distutils,因为该符号已存在于 global() 中。

It would be really simpler to rename that directory (like tests) instead of trying to fight with py.text / python internals.重命名该目录(如测试)而不是尝试使用 py.text / python 内部结构会更简单。

You can tell pytest to ignore specific files or glob patterns as described here .你可以告诉pytest描述忽略特定文件或glob模式在这里 Put a conftest.py file in the root directory of your project that lists the files you want pytest to ignore:conftest.py文件放在项目的根目录中,该文件列出了您希望pytest忽略的文件:

However, many projects will have a setup.py which they don't want to be imported.但是,许多项目都有一个他们不想导入的 setup.py。 Moreover, there may files only importable by a specific python version.此外,可能存在只能由特定 python 版本导入的文件。 For such cases you can dynamically define files to be ignored by listing them in a conftest.py file:对于这种情况,您可以通过在 conftest.py 文件中列出它们来动态定义要忽略的文件:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM