我正在为我的软件中的功能创建pytest单元测试。
在开始测试之前,pyunit似乎无法导入我的“ cache_offline”修饰符,该修饰符是在导入要在测试中测试的函数时间接导入的。
我正在使用Anaconda嵌入Python 3.7和pytest 5.2.2
我试图注释掉装饰器应用于我的函数的代码,这样做后pytest错误消失并且测试正确执行。
我的测试在./tests/scripts/test_scripts_helper.py
中,并且我在项目根.
上运行pytest
Pytest可以正确找到我的测试(请参阅错误消息),所以这里不是手头的问题。
我的测试从软件包read_tiff_tag
导入并想要测试功能vorace.scripts_helper
,该软件包从软件包safe_mkdir
导入函数vorace.core.misc
,而软件包vorace.core.vorace
则导入软件包{{1 }},其中三个功能由cache_offline
的装饰器package vorace.core.misc
我尝试在项目的根目录使用py.test
或python -m pytest
来运行测试。
我的项目具有以下结构(简化)。
代码根为./vorace
测试根目录为./tests
.
├── conftest.py
├── tests
│ ├── __init__.py
│ ├── scripts
│ │ ├── __init__.py
│ │ └── test_scripts_helper.py
│ └── tests_data
│ └── test_ROI.tif
└── vorace
├── __init__.py
├── core
│ ├── __init__.py
│ ├── misc.py
│ └── vorace.py
└── scripts
├── __init__.py
├── batch_analyzis.py
└── scripts_helper.py
我尝试过:
__init__.py
文件夹的每个子文件夹中有无空tests
。 ->没有变化conftest.py
的情况。 ->没有变化test_scripts_helper.py
文件中进行任何导入的测试(由于我的测试导致问题被注释掉)->测试正常执行我怀疑是一种循环导入问题,但一直有人告诉我它不能在python中发生。装饰者可能是这个规则的例外吗?
我的vorace.core.misc
代码和装饰器
from vorace.core import vorace
[...]
def cache_offline(cache_path=os.getcwd()):
[...]
def decorator(func):
[...]
def wrapper(*args, **kwargs):
[...]
return result
return wrapper
return decorator
def safe_mkdir(path):
[...]
vorace.core.vorace
中的修饰功能之一
from vorace.core.misc import *
[...]
@cache_offline(cache_path=".cache")
def classify_clusters_by_connectivity(xyz_data):
[...]
[...]
在项目根目录中执行py.test
的输出
==================== test session starts ====================
platform linux -- Python 3.7.3, pytest-5.2.2, py-1.8.0, pluggy-0.12.0
rootdir: /home/flo/PycharmProjects/VorAce
plugins: arraydiff-0.3, openfiles-0.3.2, doctestplus-0.3.0, remotedata-0.3.1
collected 0 items / 1 errors
==================== ERRORS ====================
_________ ERROR collecting tests/scripts/test_scripts_helper.py _________
tests/scripts/test_scripts_helper.py:1: in <module>
import vorace.scripts.scripts_helper as sh
vorace/scripts/scripts_helper.py:6: in <module>
from vorace.core.misc import safe_mkdir
vorace/core/misc.py:8: in <module>
from vorace.core import vorace
vorace/core/vorace.py:91: in <module>
@cache_offline(cache_path=".cache")
E NameError: name 'cache_offline' is not defined
如果我在0 == 0
文件中执行了一个简单的tests/scripts/test_scripts_helper.py
测试,但没有从项目中导入,则测试运行成功。
答案 0 :(得分:0)
当您运行./tests/scripts/test_scripts_helper.py
时,python会自动将./tests/scripts/
设置到PYTHONPATH中,但不会设置任何其他目录,因此从其他自定义文件导入的所有操作都会失败。
将所有工作目录设置为PYTHONPATH环境变量。 在Linux Shell上类似的东西。
PYTHONPATH="${PYTHONPATH}:$dir
答案 1 :(得分:0)
编辑:我终于得到了循环进口的确认。
与我所想相反,从模块导入特定名称
例如from x import y
中的内容可能对循环导入敏感,而import x
中的通知则不敏感。
要解决此问题,我刚刚导入了模块,并使用在函数调用前面加上模块的语法。 这里的更多信息:https://www.reddit.com/r/Python/comments/51hdup/from_import_vs_import_on_circular_import/
最终与装饰器或pytest无关的问题。
我通过将cache_offline
装饰器放在单独的软件包vorace.core.caching.py
中来解决此问题。现在,我仅从需要装饰的功能所在的vorace.core.vorace
导入此程序包。
通过这种方式,我的装饰器被人为地排除在单元测试导入的代码中,但其余代码仍可用于正常的应用程序执行。
但是pytest在这里仍然有问题,它应该不会导入失败。我仍然在回答任何可以解释为什么pytest无法导入我的装饰器的答案,并且我保留 resolve 这样的答案。