Python 使用nose在子模块中运行测试时出现导入错误

Python 使用nose在子模块中运行测试时出现导入错误,python,git-submodules,nose,Python,Git Submodules,Nose,我们使用git子模块在团队中共享公共模块 每个模块在其源文件夹中都有测试用例,并由nose运行 我在这个结构中有一个项目: /project_sample |__/project_sample | |__ __init__.py | |__ moduleA.py | |__/tests | | |__ __init__.py | | |__ moduleA_tests.py | |__/subpackage | |__ __init__.py | |__ modu

我们使用git子模块在团队中共享公共模块

每个模块在其源文件夹中都有测试用例,并由nose运行

我在这个结构中有一个项目:

/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()
/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
当我从子包的repo文件夹运行
nosetests
时,测试通过

似乎nose在子包(project_sample)的父文件夹中找到了一个init.py文件,当我从project_sample的根目录运行
nosetests
时,我得到了
“ImportError:没有名为子包的模块”
。但当我将第一行更改为:

from project_sample.subpackage import moduleB
但这种方式使得子包不是独立的

我尝试了一些类似的方法:将子包添加到
sys.path
或使用nose的
-w
选项,但仍然得到这个异常

我的队友在PyCharm中分别运行了subpackage的测试用例并通过了测试,所以我认为应该有一些方法使它从命令行通过

有没有办法解决这个问题,或者对项目结构有什么建议


这是我的第一个问题,任何建议都将不胜感激。

如果您希望子包是独立的,您需要将其视为独立的。这意味着您需要将其放在顶层,与
项目样本平行,而不是放在其中。

我知道这个问题有点老,已经得到了回答,但我们在代码库中使用了不同的策略

如果出于某种原因,您仍然希望该包位于project_sample module目录中,您可以将其结构如下:

moduleB_tests.py:

from subpackage import moduleB

def test_funcA():
    moduleB.funcA()
/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
如果子包中没有
\uuuu init\uuuu.py
,它将不会成为项目的一部分

然后在主包的
\uuuu init\uuuuuuuuuupy
中,您可以包括

导入操作系统
导入系统
系统路径插入(0,
os.path.join(
os.path.dirname(os.path.dirname(_文件__)),
“分包回购”)
)
进口分装
它将子包放在主项目的路径中

然后在
moduleA.py
中,允许我们执行以下操作

python -m unittest discover
来自。进口分装
因为包是在
\uuuu init\uuuu.py
级别导入的

当然,您也可以将其向上移动一个级别,如果您想这样做,只需在添加的路径中反映这一点。这样做的唯一缺点是,当您使用

python -m unittest discover

您还将发现子包测试并运行这些测试。理想情况下,这些测试应该与包中的任何CI一起进行,因此我们希望它们不需要运行。

感谢您的回复!它可以解决这个问题,但这意味着我们不能使包分层依赖,它的分发将包含多个文件夹。我发现同一个著名的库(比如请求)按照层次结构排列它们的包,所以应该有其他的方法。你能告诉我请求中的代码是什么吗?请注意:在Python中,拥有多个文件夹深度(或更好的:包深度)层次结构不是问题,但也不是问题所在。您试图让一个包出现在两个不同的名称下—这是不受支持的(至少在不随意弄乱
sys.path
的情况下,可能会与其他模块产生别名问题)。如果您想要自包含的,请使用顶层,不要嵌入模块层次结构的深处。谢谢您的建议。在我看来,如果一个包裹是独立的,它可以放在任何地方。我认为我的问题主要在于单元测试,特别是nose发现和运行测试的方式。项目在没有这些测试的情况下运行良好。@soulcoder思想和现实不一定一致:)Python理解中的自足与ur不同。你可以“对抗体制”,但这是有代价的。如果将
project\u sample
添加到
sys.path
,则可以“修复”问题。但这将使例如
moduleA
也成为顶级模块,可以作为
import moduleA
导入,而不是
import project\u sample.moduleA
。这可能会导致模块变量出现两次细微的错误。所以,再一次,我非常严肃的建议是:不要这样做。pip不会将请求安装到项目中。它安装在旁边。