Python 使用pytest正确导入
我刚刚准备好在Python2.6中使用pytest。到目前为止,除了处理“import”语句外,它工作得很好:我似乎无法让pytest以与我的程序相同的方式响应导入 我的目录结构如下:Python 使用pytest正确导入,python,import,pytest,Python,Import,Pytest,我刚刚准备好在Python2.6中使用pytest。到目前为止,除了处理“import”语句外,它工作得很好:我似乎无法让pytest以与我的程序相同的方式响应导入 我的目录结构如下: src/ main.py util.py test/ test_util.py geom/ vector.py region.py test/ test_vector.py
src/
main.py
util.py
test/
test_util.py
geom/
vector.py
region.py
test/
test_vector.py
test_region.py
import sys, os
sys.path.append(os.path.realpath(os.path.dirname(__file__)+"/.."))
要运行,我从src/调用python main.py
在main.py中,我使用
from geom.region import Region
from geom.vector import Vector
from geom.region import Region
在vector.py中,我使用
from geom.region import Region
from geom.vector import Vector
from geom.region import Region
当我在标准运行中运行代码时,这些都可以正常工作。然而,当我从src/调用“py.test”时,它总是以导入错误的方式退出
一些问题和我的解决方法 我的第一个问题是,当运行“test/test\u foo.py”时,py.test不能直接“导入foo.py”。我用“imp”工具解决了这个问题。在“test_util.py”中: 这对许多文件都非常有效。这似乎还意味着,当pytest运行“path/test/test_foo.py”来测试“path/foo.py”时,它基于目录“path” 但是,对于“test_vector.py”,这将失败。Pytest可以找到并导入
向量
模块,但它无法找到任何向量
的导入。使用pytest时,以下导入(来自“vector.py”)均失败:
from geom.region import *
from region import *
这两者都给出了形式上的错误
ImportError: No module named [geom.region / region]
我不知道下一步该怎么解决这个问题;我对Python导入的理解是有限的
使用pytest时,处理导入的正确方法是什么?
编辑:非常黑客的解决方案 在
vector.py
中,我将import语句从
from geom.region import Region
简单地
from region import Region
这使得导入相对于“vector.py”目录
接下来,在“test/test_vector.py”中,我将“vector.py”目录添加到路径中,如下所示:
src/
main.py
util.py
test/
test_util.py
geom/
vector.py
region.py
test/
test_vector.py
test_region.py
import sys, os
sys.path.append(os.path.realpath(os.path.dirname(__file__)+"/.."))
这使Python能够从“geom/test/test_vector.py”中查找“./region.py”
这是可行的,但问题似乎非常严重,因为我正在向路径中添加大量新目录。我要找的是
1) 与pytest兼容的导入策略,或
2) pytest中的一个选项,使其与我的导入策略兼容
因此,我将这个问题留给这些类型的答案。import在以下目录中查找模块:
sys.path是将主目录、PYTHONPATH和标准库目录相结合的结果。您正在执行的操作,修改系统路径是正确的。这是我经常做的事。如果您不喜欢与sys.path混为一谈,可以尝试使用PYTHONPATH,我也想知道如何解决这个问题。在阅读了这篇文章,并进行了一些尝试之后,我想出了一个优雅的解决方案。我创建了一个名为“test_setup.py”的文件,并将以下代码放入其中:
import sys, os
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
我把这个文件放在顶层目录中(比如src)。当从顶级目录运行pytest
时,它将运行包括此文件在内的所有测试文件,因为该文件的前缀为“test”。文件中没有测试,但它仍在运行,因为它以“test”开头
代码将把test_setup.py文件的当前目录名附加到测试环境中的系统路径。这将只执行一次,因此不会向路径添加大量内容
然后,从任何测试函数中,您可以导入与顶层文件夹相关的模块(例如import geom.region
),并且它知道在哪里可以找到它,因为src目录已添加到路径中
如果要运行单个测试文件(例如test_util.py)而不是所有文件,则可以使用:
pytest test_setup.py test\test_util.py
这将运行test_设置和test_util代码,以便test_设置代码仍然可以使用。这里的问题是Pytest遍历文件系统以发现包含测试的文件,但随后需要生成一个模块名,该模块名将导致导入该文件。(记住,) Pytest通过查找不包含
\uuuu init\uuuu.py
文件的文件级别或其上的第一个目录,并声明包含从该文件生成的模块的模块树的“basedir”。然后,它将basedir添加到sys.path
,并使用模块名导入,该模块名将找到与basedir相关的文件
您应该注意以下几点:
geom.test.test\u vector
实际上将被命名为test\u vector
,因为它在src/geom/test/
中未找到\uuu init\uuuuuuuuuuuuuuuy
,因此将该目录添加到sys.path
\uuuu init\uuuuuu.py