Pau*_*ore 42 python unit-testing pytest
我有一个项目目录结构如下(我认为这很标准):
my_project
setup.py
mypkg
__init__.py
foo.py
tests
functional
test_f1.py
unit
test_u1.py
Run Code Online (Sandbox Code Playgroud)
我正在使用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)
Run Code Online (Sandbox Code Playgroud)
这似乎有效,但它是确保测试看到应用程序代码的好方法吗?有没有更好的方法来实现这一点,或者我在如何构建项目时做错了什么?
我已经看过其他一些使用的项目py.test(例如,pip但是我看不到代码做了这样的事情,但是运行py.test tests似乎在那里工作.我不知道为什么,但我担心他们可能以更简单的方式取得了同样的结果.
我查看了py.test文档,但是我看不出这个问题的解释或建议的方法来处理它.
flu*_*lub 42
正如你所说,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
Run Code Online (Sandbox Code Playgroud)
1 包
PYTHONPATH=$(pwd)/mypkg/ python3 -m pytest
# or
PYTHONPATH=$(pwd)/mypkg/ python3 -m pytest path/to/tests
Run Code Online (Sandbox Code Playgroud)
适用于 2 包(pkg1 pkg2)
# Use ; as a separator in windows
PYTHONPATH=/path/to/pkg1/:/path/to/pkg2/ python3 -m pytest tests
Run Code Online (Sandbox Code Playgroud)
最简单的方法是在terminal / cmd更改目录到父目录的位置(例如,在这种情况下cd C:/.../my_project)。
然后运行:
python -m pytest --cov=mypkg tests
无需弄乱PYTHONPATH环境变量。通过运行python -m pytest,它将自动将当前目录添加到sys.path。