我有一个项目目录结构如下(我认为这很标准):
my_project setup.py mypkg __init__.py foo.py tests functional test_f1.py unit test_u1.py
我正在使用py.test作为我的测试框架,我希望能够py.test tests
在my_project
目录中运行以运行我的测试.这确实有效,直到我尝试import mypkg
在测试中使用(例如)导入我的应用程序代码.那时,我收到错误"没有名为mypkg的模块".在进行一些调查时,似乎py.test
运行测试与测试文件的目录sys.path
,但不是py.test
运行的目录.
为了解决这个问题,我conftest.py
在我的tests
目录中添加了一个文件,其中包含以下代码:
import sys, os # Make sure that the application source directory (this directory's parent) is # on sys.path. here = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) sys.path.insert(0, here)
这似乎有效,但它是确保测试看到应用程序代码的好方法吗?有没有更好的方法来实现这一点,或者我在如何构建项目时做错了什么?
我已经看过其他一些使用的项目py.test
(例如,pip
但是我看不到代码做了这样的事情,但是运行py.test tests
似乎在那里工作.我不知道为什么,但我担心他们可能以更简单的方式取得了同样的结果.
我查看了py.test
文档,但是我看不出这个问题的解释或建议的方法来处理它.
正如你所说,py.test基本上假设你正确设置了PYTHONPATH.有几种方法可以实现这一目标:
为您的项目提供setup.py并pip install -e .
在此项目的virtualenv中使用.这可能是标准方法.
如果您有virtualenv但没有setup.py使用您的venv工具在sys.path上添加项目目录,例如,pew add .
如果您使用pew,或者add2virtualenv .
如果您使用virtualenv和virtualenvwrapper的扩展,那么作为对此的变体.
如果您始终喜欢sys.path上的当前工作目录,则可以始终PYTHONPATH=''
在shell中导出.这是确保sys.path上的空字符串,python将其解释为当前工作目标.但这可能存在安全隐患.
我自己最喜欢的黑客,滥用py.test如何加载conftest文件:conftest.py
在项目的顶级目录中放空.
py.test以这种方式运行的原因是为了便于在结帐的test /目录中针对已安装的包运行测试.如果它无条件地将项目目录添加到PYTHONPATH,那么这将不再可能.
其实答案是很容易,因为看到这里.
您需要做的就是__init__.py
在测试目录及其每个子目录中添加一个,就像这样;
tests/__init__.py tests/functional/__init__.py tests/unit/__init__.py
最简单的方法是在terminal / cmd更改目录到父目录的位置(例如,在这种情况下cd C:/.../my_project
)。
然后运行:
python -m pytest --cov=mypkg tests
无需弄乱PYTHONPATH
环境变量。通过运行python -m pytest
,它将自动将当前目录添加到sys.path
。