我们使用 git 子模块在团队中共享公共模块。
每个模块在其源文件夹中都有测试用例,并通过鼻子运行。
我有一个结构的项目:
/project_sample
|__/project_sample
| |__ __init__.py
| |__ moduleA.py
| |__/tests
| | |__ __init__.py
| | |__ moduleA_tests.py
| |__/subpackage
| |__ __init__.py
| |__ moduleB.py
| |__/tests
| |__ __init__.py
| |__ moduleB_tests.py
|__setup.py
所有这些 init.py 文件都是空的。
子包由 git 子模块单独开发并添加到项目中。我们希望它是自包含的,并尝试在不同的项目中共享它。它的测试用例是这样的:
moduleB_tests.py:
from subpackage import moduleB
def test_funcA():
moduleB.funcA()
当我从子包的存储库文件夹运行nosetests
时,测试通过。
似乎鼻子在subpackage(project_sample)的父文件夹中找到了一个init.py文件,当我从project_sample的根目录运行nosetests
时,我得到了"ImportError: No module named subpackage"
.但是当我将第一行更改为:
from project_sample.subpackage import moduleB
但这种方式使子包不是独立的。
我尝试了一些方法,例如:将子包添加到sys.path
或使用鼻子选项-w
但仍然得到这个异常。
我的队友在 PyCharm 中单独运行 subpackage 的测试用例并获得通过,所以我认为应该有某种方法让它从命令行通过。
有没有办法解决问题,或者对项目结构有任何建议?
这是我关于SO的第一个问题,任何建议都值得赞赏。
这个问题有点旧,已经得到了回答,但我们在代码库中使用了不同的策略。
如果出于某种原因,您仍然希望将包放在 project_sample 模块目录中,您可以像这样构建它:
/project_sample
|__/project_sample
| |__ __init__.py
| |__ moduleA.py
| |__/tests
| | |__ __init__.py
| | |__ moduleA_tests.py
| |__/subpackage_repo
| |__/subpackage
| |__ __init__.py
| |__ moduleB.py
| |__/tests
| |__ __init__.py
| |__ moduleB_tests.py
| |__setup.py
|__setup.py
如果子包中没有__init__.py
,它就不会成为项目的一部分。
然后在主包的__init__.py
中,您可以包含
import os
import sys
sys.path.insert(0,
os.path.join(
os.path.dirname(os.path.dirname(__file__)),
'subpackage_repo')
)
import subpackage
这会将子包放在主项目的路径中。
然后在moduleA.py
允许我们做类似的事情
from . import subpackage
因为包是在__init__.py
级别导入的。
当然,您也可以将其提升一个级别,如果您想这样做,只需将其反映在要添加的路径中即可。这样做的唯一缺点是,当您使用类似的东西运行测试时
python -m unittest discover
您还将发现子包测试并运行这些测试。理想情况下,这些测试应该使用软件包的任何CI来处理,因此我们希望它们不需要运行。
如果您希望子包是自包含的,则需要将其视为自包含。这意味着您需要将其置于顶层,与project_sample
并行,而不是放入其中。