如何在Python中从tests模块导入src?

5

我有一个应用程序,想要使用 unittest 进行测试,但是遇到了一些问题。我的目录结构如下:

root_dir
├── src
│   ├── cmds
│   │   ├── baz.py
│   │   ├── __init__.py
│   │   └── bar.py
│   └── foo.py
└── tests
    ├── cmds.py
    └── __init__.py

我想测试来自cmdsbazbar模块,我正在尝试执行以下操作: root_dir> python2.7 -m unittest tests.cmds 但是在tests.cmds中,我无法在我的src目录中导入cmds包。
如何使其工作?
基本上,我想使用srctests目录分别测试来自root_dir的应用程序。
我尝试将src附加到sys.path,但是当我从tests/cmds.py导入cmds.baz时,仍然会从unittest获得一个AttributeError: 'module' object has no attribute 'cmds'
编辑: 我的导入和sys.path语句是:
import sys
sys.path.append('../src')
from cmds.baz import about

并且有一个回溯(traceback):

Traceback (most recent call last):
  File "/usr/lib/python2.7/runpy.py", line 162, in _run_module_as_main
    "__main__", fname, loader, pkg_name)
  File "/usr/lib/python2.7/runpy.py", line 72, in _run_code
    exec code in run_globals
  File "/usr/lib/python2.7/unittest/__main__.py", line 12, in <module>
    main(module=None)
  File "/usr/lib/python2.7/unittest/main.py", line 94, in __init__
    self.parseArgs(argv)
  File "/usr/lib/python2.7/unittest/main.py", line 149, in parseArgs
    self.createTests()
  File "/usr/lib/python2.7/unittest/main.py", line 158, in createTests
    self.module)
  File "/usr/lib/python2.7/unittest/loader.py", line 128, in loadTestsFromNames
    suites = [self.loadTestsFromName(name, module) for name in names]
  File "/usr/lib/python2.7/unittest/loader.py", line 100, in loadTestsFromName
    parent, obj = obj, getattr(obj, part)
AttributeError: 'module' object has no attribute 'cmds'

2
src不是一个包,但tests是。为什么会这样?你是否正确设置了Python路径? - pvoosten
请展示您的确切导入和完整的回溯信息。 - agf
@lbp 因为我在执行 python2.7 -m unittest tests.cmds 时必须导入它。 - Paul
1
也许问题出在你的测试文件名为 cmds.py,而模块目录名为 cmds 上 - 没有属性的“module”可能是 cmds.py - 尝试使用 import src.cmds.baz 看看是否仍然会出现错误? - BergmannF
解决了!我从测试目录(而不是根目录)运行了测试命令,并将tests/cmds.py重命名为其他名称,但仍在使用上面发布的导入语句。 - Paul
2个回答

5

一个非常错误的做法是将相对路径附加到sys.path中。如果您想确保路径正确,可以按照以下方式设置:

# assuming that the code is in test's __init__.py
import os
import sys
sys.path.insert(0, os.path.abspath( os.path.join(os.path.dirname(__file__), 
                                               '../src/') ))
# now you can be sure that the project_root_dir/src comes first in sys.path

2

我认为你的理解基本正确。但是,由于你在根目录下运行测试,所以你的路径('../src')可能是错误的。也许你可以尝试这样做:

import os
import sys

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

from cmds.baz import about

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接