我试图在添加代码库的同时改善项目结构。我发现了一个示例结构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.txt
和setup.py
的级别比tests/
和sample/
如果我添加sample/classes.py
,则只需在from classes import MyClass
中写sample/core.py
即可。但是,它不能轻易地导入到tests/test_basic.py
中,似乎不像python导入时那样“四处寻找”。
在我的情况下,还有一个MANIFEST.in
与requirements.txt处于同一级别,并且有些文件不是真正的python,只是为运行该文件的平台进行了设置。
如果classes.py
与requirements.txt
处于同一级别,我认为tests/
和sample/
及其子目录中的所有内容都可以轻松导入,但是可能需要__init__.py
感觉不对。
如果tests/
和sample/
都需要能够使用它,那应该去哪里?
答案 0 :(得分:2)
让我们变得简单
如果我的理解正确,那么问题就出在How to import simple module in test
上。这意味着您想使用类似from simple.classes import MyClass
之类的东西。
这很容易,只需在执行PYTHONPATH
之前将根路径添加到python test/test_basic.py
。
这也是IDE通过它执行测试时为您执行的操作。
答案 1 :(得分:1)
假设您使用的Python> = 3.3,只需在包中添加一个__init__.py
模块即可将包中的测试文件夹打开。然后,在该__init__.py
中(仅在那里),将父包的路径添加到sys.path
中。如果足以进行单元测试,则会发现可以将其用于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
之所以能够正常工作,是因为sample已经是一个包,并且在sys.path
加载了python unittest
包后,其父文件夹已添加到test
。
当然,这仅适用于您可以将测试放在一个包中的情况。如果出于某种原因(例如由于您需要单独运行测试模块)不是一个选择,则应将sys.path
修改直接放在所有测试文件中。
在tests文件夹中写一个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
...