Reputation: 8360
I'm having a tough time understanding packages, and specifically how to use unittest with packages. I looked at this question () but the correct answer to that question didn't solve my problem. I have the following structure:
model
|-- __init__.py
|-- boardmodel.py
|
|-- exceptions
| |
| |-- __init__.py
| |-- exceptions.py
|
|-- test
|-- __init__.py
|-- test_boardmodel.py
With the following files/imports:
model/__init__.py:
import model.exceptions.exceptions
import model.boardmodel
model/exceptions/__init__.py:
contains nothing
model/test/__init__.py:
contains nothing
imports inside boardmodel.py::
from model.exceptions.exceptions import ZeroError, OverlapError, ArgumentError, ProximityError
imports inside test_boardmodel.py:
import unittest
from model.boardmodel import Board, Ball, Wall
from model.exceptions.exceptions import ProximityError
I place myself in the model-directory and I run python -m unittest test.test_boardmodel.py
. I get the following message:
ERROR: test_boardmodel (unittest.loader._FailedTest)
----------------------------------------------------------------------
ImportError: Failed to import test module: test_boardmodel
Traceback (most recent call last):
File "/usr/local/Cellar/python3/3.6.2/Frameworks/Python.framework/Versions/3.6/lib/python3.6/unittest/loader.py", line 153, in loadTestsFromName
module = __import__(module_name)
File "/Users/sahandzarrinkoub/Documents/Programming/pythonfun/BouncingBalls/balls/src/model/test/test_boardmodel.py", line 3, in <module>
from model.boardmodel import Board, Ball, Wall
ModuleNotFoundError: No module named 'model'
I'm a bit lost with how the imports work and what location the modules/packages are looked for when an import statement is executed. Why isn't model
found?
I shall add that if I remove model.
from all the imports listed, the tests work, but I can't use the package from "outside" anymore:
src
|-- visual.py
|
|-- model
|-- __init__.py
|-- boardmodel.py
|
|-- exceptions
| |
| |-- __init__.py
| |-- exceptions.py
|
|-- test
|-- __init__.py
|-- test_boardmodel.py
inside visual.py:
import model
from model.boardmodel import Board
Upvotes: 13
Views: 19458
Reputation: 9610
I believe the standard package structure is
myproject
├── myproject
├── tests
└── scripts
If you want to run the test without installing the package, run them from the top myproject
folder so that import myproject
will succeed in your tests. (Similarly for the scripts.) For this to work, use absolute imports or explicit relative imports in myproject
.
Upvotes: 3
Reputation: 3944
Try adding the following above your import statements:
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), "..")))
Upvotes: 4
Reputation: 165
I was facing the same issue, being able to import some modules from several files, but not from a test file, so I saw this solution:
If you have test/my_test.py, tests should be run as:
python -m test.my_test
After that, I imported what I wanted and got no errors.
Upvotes: 12