Question
TextTestRunner doesn't recognize modules when executing tests in a different project
i am currently working on a project, where i need to run tests inside a different file structure like this:
/my_project
├── __init__.py
├── ...my python code
/given_proj
├── __init__.py
├── /package
│ ├── __init__.py
│ └── main.py
└── /tests
└── test_main.py
Current approach
From inside my project i want to execute the tests within the given project.
My current approach is using unittest.TextTestRunner like this:
unittest.TextTestRunner().run(unittest.defaultTestLoader.discover('../given_proj/tests'))
.
Problem with the current approach
Of course the test file wants to import from main.py
like this from package.main import my_function
. However when i run my code, the tests fail to run because the "package" module cannot be found:
...\given_proj\tests\test_main.py", line 2, in <module>
from package.main import my_function
ModuleNotFoundError: No module named 'package'
When i run the tests with python -m unittest discover -s tests
from the command line in the directory of the given_proj
they run fine.
What i tried
I tried changing the working directory to given_proj
with os.chdir('../given_proj')
however it produces the same result.
What i kinda tried, was importing the module manually with importlib.import_module()
. There i am not sure if i did it wrong or it doesnt work either.
My question
How do i make it, that the tests get run, as if i would run it from the actual directory they are supposed to run? Ideally i wouln't need to change the "given_project" at all, because i want to do this with multiple projects.
Reproducing it
I reduced it to a very minimal project, if anybody wants to try and reproduce it. The file-structure is the one at the top of the post.
All __init__.py
files are empty.
/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()