在测试和核心之间共享一个模块 - 适当的项目结构

sharing a module between tests and core - appropriate project structure

我正在尝试在添加代码库的同时改进项目结构。我找到了一个示例结构 here,它看起来像这样:

README.rst
LICENSE
setup.py
requirements.txt
sample/__init__.py
sample/core.py
sample/helpers.py
docs/conf.py
docs/index.rst
tests/test_basic.py
tests/test_advanced.py

我特别注意到 requirements.txtsetup.py 的水平高于 tests/sample/

如果我添加 sample/classes.py,您只需在 sample/core.py 中写入 from classes import MyClass 即可。然而,它不能那么容易地导入到 tests/test_basic.py,导入时看起来不像 python 'looks around the corner'。

在我的例子中,还有一个 MANIFEST.in 与 requirements.txt 处于同一级别,一些文件实际上不是 python,只是为平台设置了东西这运行。

如果 classes.pyrequirements.txt 处于同一级别,我认为 tests/sample/ 及其子目录中的所有内容都可以轻松导入它,但是它可能需要 __init__.py 感觉有点不对。

那么如果 tests/sample/ 都需要能够使用它,那么它应该去哪里呢?

让我们轻松一点。

如果我没理解错的话,问题是How to import simple module in test。这意味着您想使用 from simple.classes import MyClass.

之类的东西

这很简单,只需在执行 python test/test_basic.py 之前将您的根路径添加到 PYTHONPATH

这也是 IDE 在您通过它执行测试时为您做的事情。

假设你使用的是Python >= 3.3,你可以通过在其中添加一个__init__.py模块来简单地将测试文件夹变成一个包。然后在 __init__.py 中(并且仅在此处)将父包的路径添加到 sys.path。如果足以让 unittest 发现将它用于 tests.

中的所有模块

我的是:

import os
import sys

sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))

然后,如果您需要从其中一个测试模块访问 classes.py,您可以使用:

from sample import classes

或者直接导入MyClass:

from sample.classes import MyClass

之所以有效,是因为示例已经是一个包,并且当 python unittest 加载了 test 包时,它的父文件夹已添加到 sys.path


当然,这只适用于您可以将测试放在一个包中。如果出于任何原因它不是一个选项,例如因为你需要单独 运行 测试模块,那么你应该将 sys.path 修改直接放在所有测试文件中。

在测试文件夹中写一个path_helper.py文件:

import os
import sys

core_path = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
if core_path not in sys.path:  # don't add it if it is already here
    sys.path.append(core_path)

然后您可以在所有测试文件中导入它:

import path_helper
...