Reputation: 103
I am trying to make unit tests for my project, but I am having issues figuring out where my error is in regards to absolute importing the module to test. I am using Visual Studio Code as my IDE.
My directories look like this:
project_folder
+ code_files
- reader.py
- __init__.py
+ tests
- test_reader.py
- data.txt
- __init__.py
My "test_reader.py" file looks like this:
import unittest
from code_files.reader import Reader
class Test_LineCounter(unittest.TestCase):
def test_empty_file_long(self):
self.assertEqual(Reader.line_counter(self, "data.txt"), 4)
if __name__ == "__main__":
unittest.main()
However, I keep getting the error:
ModuleNotFoundError: No module named 'code_files'
To be completely honest, when I was going into this project I was not very strong working with directories, packages, or modules. I have read many articles online and have read many forum posts on Stack Overflow and other websites trying to figure out what may be causing this error and how I can resolve it. Through this, I feel like I have gained a pretty good understanding of how Python handles packages and modules. Yet I still can't seem to get this problem figured out.
I have tried putting the "code_files" package into a different directory to see if that would work:
project_folder
+ app
+ code_files
- reader.py
- __init__.py
And then imported by:
from app.code_files.reader import Reader
But then I got the error:
ModuleNotFoundError: No module named 'app'
The only time I managed to get "test_reader" to work was when I had my directory structed as follows:
project_folder
+ code_files
- reader.py
- __init__.py
+ test_reader.py
+ data.txt
+ __init__.py
Any help would be greatly appreciated! I feel like there is a very simple solution to this that I just keep overlooking. I know very similar questions have been asked on here before, but all of the determined solutions I have seen are what I have already tried or am currently doing. So I apologize if this is a repetitive question. Thanks!
Upvotes: 10
Views: 14451
Reputation: 8431
Reason:
This is because the folder of project_folder
was not in the sys.path.
A list of strings that specifies the search path for modules. Initialized from the environment variable PYTHONPATH, plus an installation-dependent default.
As initialized upon program startup, the first item of this list, path[0], is the directory containing the script that was used to invoke the Python interpreter.
This can explain the problem you have met.
When the test_reader.py
is under the tests
folder, tests
folder will be added to the sys.path
. When the test_reader.py
is under the project_folder
folder, project_folder
folder will be added to the sys.path
. Then the python interpreter can find the code_files
package.
Solution:
How do you run the test? If you run the test through the Test Panel you will not run across the module problem:
And it will automatically add the workspace folder to the sys.path
. So, it's recommended to run the test in this way.
tips:
If you want to get the
sys.path
, you can add thepprint(sys.path)
after theself.assertEqual(Reader.line_counter(self, "data.txt"), 4)
. But you can only get the result in the channel ofPython Test Log
in theOUTPUT
panel.
If you debug(F5) the test, you can add this in the launch.json file:
"env": {"PYTHONPATH":"${workspaceFolder}"},
If you run the test with the command in ter terminal. You should modify the sys.path
in the test file:
sys.path.append("the path to the project_folder folder")
Upvotes: 8
Reputation: 134
You must add this to the beginning of test_reader.py
# test_reader.py
import sys
sys.path.append('/.../project_folder/code_files')
import reader
Replace the ...
with the concrete path, so if it is in Desktop on Windows then it would be 'C:/Users/USERNAME/Desktop/project_folder' and so on...
Here is a link to further information
Upvotes: -2