NcA*_*ams 35 python import pytest
我刚刚设置为使用python与Python 2.6.到目前为止,除了处理"导入"语句之外,它运行良好:我似乎无法以与我的程序相同的方式响应导入.
我的目录结构如下:
src/
main.py
util.py
test/
test_util.py
geom/
vector.py
region.py
test/
test_vector.py
test_region.py
Run Code Online (Sandbox Code Playgroud)
要运行,我python main.py从src/调用.
在main.py中,我导入了vector和region
from geom.region import Region
from geom.vector import Vector
Run Code Online (Sandbox Code Playgroud)
在vector.py中,我导入了区域
from geom.region import Region
Run Code Online (Sandbox Code Playgroud)
当我在标准运行中运行代码时,这些都可以正常工作.但是,当我从src /调用"py.test"时,它会一直退出导入错误.
我的第一个问题是,当运行"test/test_foo.py"时,py.test无法直接"导入foo.py".我通过使用"imp"工具解决了这个问题.在"test_util.py"中:
import imp
util = imp.load_source("util", "util.py")
Run Code Online (Sandbox Code Playgroud)
这适用于许多文件.它似乎也暗示当pytest运行"path/test/test_foo.py"来测试"path/foo.py"时,它基于目录"path".
但是,"test_vector.py"失败了.Pytest可以找到并导入vector模块,但它无法找到任何vector的进口.使用pytest时,以下导入(来自"vector.py")都会失败:
from geom.region import *
from region import *
Run Code Online (Sandbox Code Playgroud)
这些都给出了表格的错误
ImportError: No module named [geom.region / region]
Run Code Online (Sandbox Code Playgroud)
我不知道接下来要做什么来解决这个问题; 我对Python中导入的理解是有限的.
使用pytest时处理导入的正确方法是什么?
在vector.py,我更改了import语句
from geom.region import Region
Run Code Online (Sandbox Code Playgroud)
简单地说
from region import Region
Run Code Online (Sandbox Code Playgroud)
这使得导入相对于"vector.py"目录.
接下来,在"test/test_vector.py"中,我将"vector.py"目录添加到路径中,如下所示:
import sys, os
sys.path.append(os.path.realpath(os.path.dirname(__file__)+"/.."))
Run Code Online (Sandbox Code Playgroud)
这使Python能够从"geom/test/test_vector.py"中找到"../region.py".
这是有效的,但它似乎非常有问题,因为我在路径中添加了大量的新目录.我正在寻找的是
1)与pytest兼容的导入策略,或
2)pytest中的一个选项,使其与我的导入策略兼容
所以我将这个问题留给这些问题的答案.
off*_*pta 21
如果您在测试目录中包含一个__init__.py文件,那么当程序要设置主目录时,它将“向上”移动,直到找到不包含 init 文件的主目录。在这种情况下 src/.
从这里你可以通过说导入:
from geom.region import *
Run Code Online (Sandbox Code Playgroud)
您还必须确保在任何其他子目录中都有一个 init 文件,例如其他嵌套的测试目录
Cur*_*son 16
这里的问题是Pytest遍历文件系统以发现包含测试的文件,但随后需要生成一个模块名称,该名称将导致import加载该文件.(请记住,文件不是模块.)
Pytest 通过查找不包含文件的文件级别或更高级别的第一个目录,并声明包含从该文件生成的模块的模块树的"basedir" 来提供此测试包名称__init__.py.然后它sys.path使用模块名称将basedir添加到前面并导入,该模块名称将找到相对于basedir的文件.
您应该注意这一点的一些含义:
基本路径可能与您的预期基路径不匹配,在这种情况下,模块的名称将与您通常使用的名称不匹配.例如,你所认为的geom.test.test_vector实际上将刚刚任命test_vector的Pytest运行过程中,因为它没有发现__init__.py的src/geom/test/,因此补充说,到路径.
如果不同目录中的两个文件具有相同的名称,则可能会遇到模块命名冲突.例如,缺少sys.path文件的任何地方,添加__init__.py将与冲突geom/test/test_util.py,因为两者都加载test/test_util.py,既import test_util.py和test/路径.
您在这里使用的系统,没有显式geom/test/模块,就是让Python 为您的目录创建隐式命名空间包.(包是一个带有子模块的模块.)理想情况下,我们将为Pytest配置一个路径,从中也可以生成它,但它似乎不知道如何做到这一点.
这里最简单的解决方案就是将空__init__.py文件添加到所有子目录下__init__.py; 这将导致Pytest使用以目录名开头的包/模块名称导入所有内容src/.
Jos*_*rez 15
import在以下目录中查找以查找模块:
sys.path中是结合的结果主目录, PYTHONPATH和标准库目录.你正在做什么,修改 sys.path是正确的.这是我经常做的事情.如果您不喜欢使用 sys.path,可以尝试使用 PYTHONPATH
小智 9
很晚才回答这个问题,但使用 python 3.9 或 3.10 你只需要__init__.py在测试文件夹中添加文件夹。
当你添加这个文件时,python 将此文件夹解释为一个模块。会是这样
src/
main.py
util.py
test/
__init__.py
test_util.py
geom/
vector.py
region.py
test/
__init__.py
test_vector.py
test_region.py
Run Code Online (Sandbox Code Playgroud)
所以你就跑吧pytest。
抱歉我的英语不好
我想知道该怎么办这个问题.看了这篇文章,并玩了一下,我想出了一个优雅的解决方案.我创建了一个名为"test_setup.py"的文件,并将以下代码放入其中:
import sys, os
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
Run Code Online (Sandbox Code Playgroud)
我把这个文件放在顶级目录(例如src)中.当pytest从顶级目录运行时,它将运行包括此文件在内的所有测试文件,因为该文件的前缀为"test".文件中没有测试,但它仍然运行,因为它以"test"开头.
代码将test_setup.py文件的当前目录名附加到测试环境中的系统路径.这只会进行一次,因此路径中没有添加任何东西.
然后,从任何测试函数中,您可以导入相对于该顶级文件夹的模块(例如import geom.region),并且它知道在将src目录添加到路径之后的位置.
如果要运行单个测试文件(例如test_util.py)而不是所有文件,则可以使用:
pytest test_setup.py test\test_util.py
Run Code Online (Sandbox Code Playgroud)
这将运行test_setup和test_util代码,以便仍可以使用test_setup代码.
| 归档时间: |
|
| 查看次数: |
18936 次 |
| 最近记录: |