我目前正在开发一个项目,我需要在不同的文件结构中运行测试,如下所示:
/my_project
├── __init__.py
├── ...my python code
/given_proj
├── __init__.py
├── /package
│ ├── __init__.py
│ └── main.py
└── /tests
└── test_main.py
在我的项目内部,我想在给定项目中执行测试。 我当前的方法是使用unittest.TextTestRunner,如下所示:
unittest.TextTestRunner().run(unittest.defaultTestLoader.discover('../given_proj/tests'))
。
当然,测试文件要像这样
main.py
一样从from package.main import my_function
导入。但是,当我运行代码时,测试无法运行,因为找不到“package”模块:
...\given_proj\tests\test_main.py", line 2, in <module>
from package.main import my_function
ModuleNotFoundError: No module named 'package'
当我从
python -m unittest discover -s tests
目录中的命令行使用 given_proj
运行测试时,它们运行良好。
我尝试使用
given_proj
将工作目录更改为 os.chdir('../given_proj')
,但它会产生相同的结果。
我尝试过的是使用
importlib.import_module()
手动导入模块。我不确定我是否做错了或者它也不起作用。
我该如何运行测试,就像我从他们应该运行的实际目录运行它一样?
如果有人想尝试并重现它,我将其缩减为一个非常小的项目。文件结构是帖子顶部的结构。
所有
__init__.py
文件都是空的。
/my_project/main.py
:
import os
import unittest
import os
import unittest
if __name__ == "__main__":
dirname = "../given_proj/tests" #either "./" or "../" depending of where you run the python file from
unittest.TextTestRunner().run(unittest.defaultTestLoader.discover(dirname))
/given_proj/package/main.py
:
def my_function(num):
return num*2
/given_proj/tests/test_main.py
:
import unittest
from package.main import my_function
class TestMain(unittest.TestCase):
def test_my_function(self):
result = my_function(5)
self.assertEqual(result, 10)
result = my_function(10)
self.assertEqual(result, 20)
result = my_function(0)
self.assertEqual(result, 0)
if __name__ == '__main__':
unittest.main()
一个可能的解决方案是在您的文件中添加以下指令
test_main.py
:
import unittest
import sys # <-- add this import
sys.path.insert(1, '..') # <-- add this instruction
from package.main import my_function
class TestMain(unittest.TestCase):
def test_my_function(self):
result = my_function(5)
self.assertEqual(result, 10)
result = my_function(10)
self.assertEqual(result, 20)
result = my_function(0)
self.assertEqual(result, 0)
if __name__ == '__main__':
unittest.main()
如果我在我的系统上执行测试方法
test_my_function()
,它就会通过。