gpt4 book ai didi

python - pytest 无法导入本地模块(改为导入内置模块)

转载 作者:行者123 更新时间:2023-12-01 08:14:02 27 4
gpt4 key购买 nike

我有以下 Python 2.7 简化项目结构:

project/
├── libs/
| └── zipfile.py
├── tests/
| ├── __init__.py
| └── test_hello.py
├── hello.py
└── main.py

我希望此项目使用位于 libs 中的 Python 内置模块之一(在本示例中为 zipfile)的修补版本。请注意,这是一个外部需求,我无法更改项目结构。

<小时/>

以下是每个文件的简化实现:

libs/zipfile.py

def is_zipfile(filename):
return "Patched zipfile called"

测试/test_hello.py

from hello import hello

def test_hello():
assert hello() == "Patched zipfile called"

hello.py

import os
import sys

libs_path = os.path.abspath(os.path.join(os.path.dirname(__file__), "libs"))
if libs_path not in sys.path:
sys.path.insert(1, libs_path)

import zipfile

def hello():
print(zipfile.__file__) # to check which zipfile module is imported
result = zipfile.is_zipfile("some_path")
return result

ma​​in.py

from hello import hello

def main():
print(hello())

if __name__ == "__main__":
main()
<小时/>

直接运行程序(python main.py)时,我得到了预期的结果:

/home/project/libs/zipfile.pyc
Patched zipfile called

但是,当使用 project 作为工作目录(pytest -s)运行 pytest 时,它失败了:

/usr/lib/python2.7/zipfile.pyc
================================== FAILURES ===================================
_________________________________ test_hello __________________________________

def test_hello():
> assert hello() == "Patched zipfile called"
E assert False == 'Patched zipfile called'
E + where False = hello()

tests/test_hello.py:4: AssertionError
========================== 1 failed in 0.13 seconds ===========================

我尝试了 this SO post 中提出的几个解决方案,例如运行 python -m pytest ,但没有一个对我有用。有没有办法以非 hacky 的方式成功运行此测试?

最佳答案

未导入已修补的 zipfile 模块的原因是它已在测试开始之前导入(可能由 pytest 或其依赖项之一导入)

我通过将其放在 hello.py 的顶部来验证这一点:

if 'zipfile' in sys.modules:
raise AssertionError('zipfile already imported')

然后我得到:

$ ./venv/bin/python -mpytest tests
============================= test session starts ==============================
platform linux -- Python 3.6.7, pytest-4.3.0, py-1.8.0, pluggy-0.9.0
rootdir: /tmp/x, inifile:
collected 0 items / 1 errors

==================================== ERRORS ====================================
_____________________ ERROR collecting tests/test_hello.py _____________________
tests/test_hello.py:1: in <module>
from hello import hello
hello.py:5: in <module>
raise AssertionError('zipfile already imported')
E AssertionError: zipfile already imported
!!!!!!!!!!!!!!!!!!! Interrupted: 1 errors during collection !!!!!!!!!!!!!!!!!!!!
=========================== 1 error in 0.14 seconds ============================

您可以从 sys.modules 中删除 zipfile,然后您的副本可能是唯一导入的:

sys.modules.pop('zipfile', None)
也就是说,所有这一切似乎都可能是一个坏主意,因为任何已经导入该模块的人都可以访问旧的 zipfile,并且删除 stdlib 实现很有可能破坏第三方库没想到会这样。

通过直接修补 zipfile 模块上的各个方法(使用类似 mock.patch.object(zipfile, 'fn', ...) 的内容,您可能会有更好的运气)

关于python - pytest 无法导入本地模块(改为导入内置模块),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55071225/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com