pytest 集成 - 如何正确导入

pytest integration - how to properly import

我正在使用 py.test 来测试我的 python 代码。我项目的相关结构是

-myproject
    file.py
    file2.py
    -test/
        input.txt
        input2.dat
        test_part.py
    -regress/
        file2_old.py
        __init__.py
        -test/
            test_file2_regression.py

test_part.py 导入 filefile2test_file2_regression.py 导入 file2regress.file2_old。如果我在控制台中 运行 pytest,我会收到导入错误,即包不存在。另一方面,运行 python -m pytest 工作得很好,但前提是我 运行 它来自 myproject/ 目录。

执行此操作的正确方法是什么,以使其在我的项目中的任何位置工作?我已经尝试修改 PYTHONPATH 但老实说我不知道​​如何正确地修改它。


更多信息:

我没有任何安装文件,我的 __init__ 只是空文件。如果需要操作 PYTHONPATH,则需要相对于 myproject 进行操作,因为我在多台机器上使用它。我是 运行宁 python 2.7.


我已经退房了:

但这并没有真正帮助我。

在搜索 "the best way of doing this" 时遇到同样的问题和类似的成功,我总结自己尽可能避免这种情况(通过 运行 实际脚本从顶层开始),但要回答你的问题,我目前的方法(例如从并行文件夹进行单元测试)是

from sys import argv, path
from os.path import dirname, join
path.append(join(dirname(argv[0]), ".."))

这使得解释器也会在上面启动脚本的文件夹中进行搜索。另一种方法(而不是使用 argv)是使用 introspect 模块来获取文件名。这些对我来说比使用 __file__ 更有效,因为后者并不总是被定义。

编辑 29.10.: argv[0] 的替代方法是使用

from inspect import getsourcefile
from sys import path
from os.path import dirname, join

this_file = getsourcefile(lambda _: None)
path.append(join(dirname(this_file), ".."))

我希望这至少能达到要求的目的,另请参阅 How do I get the path of the current executed file in Python?

最简单的——如果它适用于你的情况——当然是:

from os.path import dirname, join
path.append(join(dirname(__file__), ".."))

从项目中的任何目录使用 pytest 命令的解决方案是在 test*.py 文件中的导入之前包含:

import os
from sys import path
PATH = os.path.abspath(os.path.dirname(__file__))
path.append(os.path.join(PATH, os.pardir, os.pardir))

正确数量的 os.pardir 用于导航到项目目录,__init__.py 文件允许从那里导入模块。

argv[0]inspect.getsourcefile 都没有提供必要的信息。 argv[0] 包含使用的 py.test 模块的位置和 getsourcefile 方法简单 returns None.


编辑:从 Python 3.4 开始,我们可以使用现代 pathlib:

而不是 os.path
from pathlib import Path
from sys import path

PATH = Path(__file__).resolve()
path.append(PATH.parents[2])