如何在Python单元测试中导入一个模块?

huangapple go评论86阅读模式
英文:

How to import a module in Python unit test?

问题

  1. ├── mymodule
  2. ├── __init__.py
  3. └── foo.py
  4. ├── tests
  5. ├── __init__.py
  6. ├── utils.py
  7. └── test_module.py

我有上述的目录结构用于我的Python包。

test_module.py文件中,我需要导入tests/utils.py。我应该如何导入它,以便我可以通过以下两种方式运行测试:

  • python tests/test_module.py
  • pytest
    从根目录?

目前,我在test_module.py文件中导入了tests/utils.py如下:

  1. from utils import myfunction

然后,pytest会生成以下错误:

  1. E ModuleNotFoundError: No module named 'utils'

如果我更改为:

  1. from .utils import myfunction

然后,pytest可以正常工作,但python tests/test_module.py会生成以下错误:

  1. ImportError: attempted relative import with no known parent package

我应该如何正确地导入utils.py,以便我可以两种方式都使用它?

  1. <details>
  2. <summary>英文:</summary>

.
├── mymodule
│ ├── init.py
│ └── foo.py
├── tests
├── init.py
├── utils.py
└── test_module.py

  1. I have the above directory structure for my Python package.
  2. Within the `test_module.py` file, I need to import `tests/utils.py`. How should I import it so that I can run the test by using both
  3. - `python tests/test_module.py`
  4. - `pytest`
  5. from the root directory?
  6. Currently, I imported `tests/utils.py` as follows in the `test_module.py` file:
  7. ```python
  8. from utils import myfunction

Then, pytest will generate the following error:

  1. E ModuleNotFoundError: No module named &#39;utils&#39;

If I change to:

  1. from .utils import myfunction

Then, pytest works fine, but python tests/test_module.py generates the following error:

  1. ImportError: attempted relative import with no known parent package

How can I properly import utils.py so that I can use in both ways?

答案1

得分: 1

  • 当你从根目录使用 pytest 运行测试时,test_module.py 会作为一个Python模块启动,因此允许相对导入。

  • 当你使用 python tests/test_module.py 运行测试时,它会作为脚本启动,不允许相对导入。但是Python会将 {根目录}/tests 目录添加到 sys.path 中,所以你可以这样导入:

    1. from utils import myfunction

你可以结合这两种情况使用以下方式:

  1. try:
  2. from .utils import myfunction
  3. except ImportError:
  4. from utils import myfunction

为了避免这个 try 语句,另一种解决方案是从根目录使用 python3 -m tests.test_module 运行脚本(参考 PEP 338)。在这种情况下,test_module.py 作为一个模块加载,相对导入 from .utils import myfunction 将正常工作。

英文:
  • When you run test with pytest from root directory, test_module.py is launch as a python module, so relative import is allowed.

  • When you run test with python tests/test_module.py, it is launch as script and relative import is not allowed. But python adds {root directory}/tests directory to sys.path. So you can import with:

    1. from utils import myfunction

You can mix these 2 cases with:

  1. try:
  2. from .utils import myfunction
  3. except ImportError
  4. from utils import myfunction

To avoid this try statement, another solution is to run the script with python3 -m tests.test_module from the root directory (PEP 338). In this case test_module.py is loaded as a module and the relative import from .utils import myfunction works fine.

huangapple
  • 本文由 发表于 2023年4月17日 04:52:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/76030280.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定