Python pytest导入本地模块的模块

6
我有以下Python3项目结构:
tests/
    - testsuite_service1/
        - test_main.py
    - testsuite_service2/
        - test_main.py
src/
    - service1/
       - codebase/
           - __init__.py
           - main.py
           - logger.py
           - waiter.py
    - service2/
       - codebase/
           - __init__.py
           - main.py
           - logger.py
           - waiter.py

在我的测试中(pytest),我这样导入:
```python from src.service1.codebase.waiter import check_status ```
为了从service1模块中导入特定的函数。
在service1中的waiter.py中,我这样从logger.py中导入一个函数:
```python from logger import configure_logger ```
然而,当运行测试时,我会得到以下错误提示:
Traceback:
tests/test_main/test_main.py:3: in <module>
    from src.service1.codebase.waiter import check_status
src/codebase/waiter.py:8: in <module>
    from logger import configure_logger
E   ModuleNotFoundError: No module named 'logger'.

当测试运行时出现这种情况,感觉像waiter.py没有在本地目录中查找logger.py,而可能是在其他位置?将其更改为from .logger import configure_logger可以解决问题,但会导致我计划部署此代码的运行时发生错误Unable to import module 'main': attempted relative import with no known parent package,因此需要单独的service1的zip包而不是父目录。是否有可能不使用相对导入并使我的测试了解如何找到所需的文件?

你尝试过使用 from src.service1.codebase.logger import configure_logger 吗? - b-fg
似乎你在包的根目录下缺少一个__init__.py文件? - b-fg
1
可能是使用带有src层的pytest的重复问题。 - hoefling
2个回答

7

在代码库/文件夹的__init__.py中添加import os, sys; sys.path.append(os.path.dirname(os.path.realpath(__file__)))解决了这个问题。


1
谢谢,这对我有用。您能否解释一下为什么添加sys.path会使导入正确? - Xavier Silva
1
@XavierSilva,它的工作原理是将包/目录名称添加到您的路径中。因此,该包中的任何模块都可以被访问和导入。 - CodeBiker

1

src应该在根目录下包含__init__.py文件以表示它是一个包。然后您可以使用绝对或相对路径从其他文件导入。绝对路径为:

from src.service1.codebase.logger import configure_logger

但是您的相对路径应该在包含__init__.py文件之后起作用。

查看此答案以获取更多信息。


谢谢 - 但是 src 文件夹在最终的压缩文件中不存在。实际上,在部署时,只有每个服务内 /codebase 文件夹中的内容会被部署,因此它不会知道关于 src(甚至是 codebase 文件夹)文件路径的任何信息,这就是为什么如果可能的话需要保留 import x from y。也许我需要将我的测试移动到各自的服务文件夹中? - djsnakz
你应该在答案中包含这些信息... 无论如何,这很可能是与Python路径相关的IDE配置问题。 - b-fg

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接