在Python中使用unittest进行相对导入

Relative imports with unittest in Python

我正在尝试使用python unittest和相对导入,但我似乎无法理解。我知道有很多相关的问题,但到目前为止,它们都没有帮助。对不起,如果这是重复的,但我真的很感谢任何帮助。我试着使用pep 328 http://www.python.org/dev/peps/pep-0328/中的语法,但我肯定有什么问题。

我的目录结构是:

1
2
3
4
5
6
7
8
9
10
11
project/
    __init__.py
    main_program.py
    lib/
        __init__.py
        lib_a
        lib_b
    tests/
        __init__.py
        test_a
        test_b

我运行测试时使用:

1
python -m unittest test_module1 test_module2

测试_a需要同时导入lib/lib_a和主_程序。这是我尝试用于导入的测试代码:

1
2
from ..lib import lib_a as lib
from ...project import main_program

两者都会引发此错误:

1
ValueError: Attempted relative import in non-package

所有init.py文件当前都为空。

任何具体建议都将不胜感激!!

编辑:

答案可能是:python包?我还在核实这是否可行。

编辑二:

为了澄清这一点,我尝试以3种不同的方式运行我的测试文件:

1
2
3
project/tests $ python -m unittest test_a
project/tests $ python -m test_a
project/tests $ ./test_a

所有三个都失败,错误与上述相同。当我使用相同的三种语法但在项目目录中时,我会得到以下错误:

1
ValueError: Attempted relative import beyond toplevel package

再次感谢。


根据我的经验,如果您的项目根不是包,那么最简单的方法是:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
project/
  test.py
  run.py
  package/
    __init__.py
    main_program.py
    lib/
      __init__.py
      lib_a
      lib_b
    tests/
      __init__.py
      test_a
      test_b

但是,从python 3.2开始,unittest模块提供了-t选项,它允许您设置顶级目录,因此您可以这样做(从package/中):

1
python -m unittest discover -t ..

有关更多详细信息,请参阅UnitTest文档。


我用同样的问题跑步,凯的回答解决了问题。我只想用test.py的内容来补充他的回答(正如@gsanta所问的)。我只在python 2.7上测试过它:

1
2
3
4
5
6
7
8
from packages.tests import test_a, test_b
import unittest

# for test_a
unittest.main(test_a)

# for test_b
unittest.main(test_a)

然后你就可以

1
../project $ python test.py