我正在努力让导入为我的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的做法是什么?
答案 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)
添加新测试非常简单,您只需要修改测试模块列表。