Python3相对Imports包内

时间:2015-12-30 05:34:27

标签: python unit-testing python-3.x python-import

我意识到StackOverflow上已经存在很多关于此问题的问题,但我发现解决方案完全不清楚并且经常相互矛盾。

我有以下场景:我正在编写一个包含以下结构的python(Python 3.4)包:

mypackage/
    __init__.py (empty file)
    mydir1/
        __init__.py (empty file)
        mymodule1.py
    mydir2/
        __init__.py (empty file)
        mymodule21.py
        mymodule22.py
    mydir3/
        __init__.py (empty file)
        mymodule31.py
        mymodule32.py
    tests/
        __init__.py (empty file)
        test_something_in_mydir1.py
        test_something_in_mydir2.py
        test_something_in_mydir3.py

我希望tests/目录中的文件包含包内所有内容的单元测试。问题是,无论我尝试哪种方法,我都会收到此错误:

SystemError: Parent module '' not loaded, cannot perform relative import

我应该注意到我希望这个“开箱即用”,这意味着我不想使用它们的绝对路径导入东西,我不想改变我的路径变量。这些解决方案中没有一个看起来非常pythonic,它驱使我慢慢上升到墙上。有没有办法做到这一点?

我已经尝试了很多东西,包括下面的例子,但它们似乎都产生了相同的结果:

from ..mydir1.mymodule1 import *
from .mypackage.mydir1.mymodule1 import *
from ...mypackage.mydir1.mymodule1 import *

我尝试覆盖每个__all__文件中的__init__.py变量以及执行导入,如下所示:https://docs.python.org/3/reference/import.html#submodules

任何人都可以告诉我如何在文件test_something_in_mydir1.py中构建导入(例如),以便能够访问mymodule1.py中的所有类/函数,以便对包进行单元测试?

1 个答案:

答案 0 :(得分:1)

如果test_something_in_mydir1.py包含:

import unittest
from ..mydir1 import mymodule1

class Test1(unittest.TestCase):
    def test1(self):
        self.assertEqual(mymodule1.x,1) # mymodule1 trivially contains x=1

如果使用以下命令从包含包的目录(在本例中为C:\Test)启动单元测试:

py -m unittest discover -v

使用相对导入发现并正确运行测试:

C:\Test>tree /f
Folder PATH listing
Volume serial number is CE8B-D448
C:.
└───mypackage
    │   __init__.py
    │
    ├───mydir1
    │       mymodule1.py
    │       __init__.py
    │
    ├───mydir2
    │       mymodule21.py
    │       mymodule22.py
    │       __init__.py
    │
    ├───mydir3
    │       mymodule31.py
    │       mymodule32.py
    │       __init__.py
    │
    └───tests
            test_something_in_mydir1.py
            __init__.py


C:\Test>py -m unittest discover -v
test1 (mypackage.tests.test_something_in_mydir1.Test1) ... ok

----------------------------------------------------------------------
Ran 1 test in 0.000s

OK