如何让导入与python包和测试包一起使用

时间:2018-06-17 20:01:26

标签: python import python-unittest

我正在努力让导入为我的python项目工作。我已经创建了一个测试项目来说明我的问题。这是Python 3。

我的目录结构如下:

project/
  test.sh
  packageA/
     __init__.py
     moduleA.py
     test/
        __init__.py
        test_moduleA.py

test.sh的内容为python3 packageA/test/test_moduleA.py

__init__py都是空的。

这是moduleA.py

class A:
  def doSomething(self):
    print("Did something")

这是'test_moduleA.py`:

import unittest
from packageA.moduleA import A

class TestModuleA(unittest.TestCase):
  def testSomething(self):
    a = A()
    self.assertTrue(a.doSomething() == "Did Something")

if __name__ == '__main__':
    unittest.main()

当我运行test.sh时,这是我得到的错误:

[project] $ ./test.sh 
Traceback (most recent call last):
  File "packageA/test/test_moduleA.py", line 2, in <module>
    from packageA.moduleA import A
ModuleNotFoundError: No module named 'packageA'
[project] $ 

我尝试在`test_moduleA.py'中使用相对导入,如下所示:

from ..moduleA import A

在这种情况下,我得到的错误如下所示:

[project] $ ./test.sh 
Traceback (most recent call last):
  File "packageA/test/test_moduleA.py", line 2, in <module>
    from ..moduleA import A
ValueError: attempted relative import beyond top-level package
[project] $

如何让它正常工作? Pythonic的做法是什么?

2 个答案:

答案 0 :(得分:1)

这是我建议的解决方案,基于this answer(另请参阅here)和this article

首先,将测试目录移动到项目的根目录中:

project/
  test.sh
  packageA/
     __init__.py
     moduleA.py
  test/
     __init__.py
     test_moduleA.py

然后,按如下所示更改test_moduleA.py(注意导入):

import unittest
from packageA.moduleA import A


class TestModuleA(unittest.TestCase):
    def testSomething(self):
        a = A()
        self.assertTrue(a.do_something() == "Something was done")

test.sh就是这个:

#!/bin/bash
TEST_PACKAGE="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"

cd ${TEST_PACKAGE}
python3 -m unittest test.test_moduleA

为了通过考试,我也改变了一个班级:

class A:
    def do_something(self):
        print("do_somwthing was called")
        return "Something was done"

现在,运行test.sh它应该按预期工作:

$ ./test.sh 
do_somwthing was called
.
----------------------------------------------------------------------
Ran 1 test in 0.000s

OK

答案 1 :(得分:0)

使用shell脚本来测试/部署python的东西并不是一个好主意,所以我建议你用test.py替换test.sh,其内容将是:

import unittest

testmodules = [
    'packageA.test.test_moduleA',
]

suite = unittest.TestSuite()

for t in testmodules:
    try:
        mod = __import__(t, globals(), locals(), ['suite'])
        suitefn = getattr(mod, 'suite')
        suite.addTest(suitefn())
    except (ImportError, AttributeError):
        suite.addTest(unittest.defaultTestLoader.loadTestsFromName(t))

unittest.TextTestRunner().run(suite)

添加新测试非常简单,您只需要修改测试模块列表。