I want to put all my unit tests in a separate directory. My project layout looks like this:
project
package
__init__.py
package.py
tests
__init__.py
package_test.py
package_test.py looks like:
from unittest import TestCase
from package import Service
class ServiceTest(TestCase):
def test_build():
service = Service.build()
self.assertIsNotNone(service)
When I try to run the tests I get the following error
$ cd project
$ nosetest
E
======================================================================
ERROR: Failure: ImportError (cannot import name 'ScraperService')
----------------------------------------------------------------------
Traceback (most recent call last):
File "/usr/local/lib/python3.6/site-packages/nose/failure.py", line 39, in runTest
raise self.exc_val.with_traceback(self.tb)
File "/usr/local/lib/python3.6/site-packages/nose/loader.py", line 418, in loadTestsFromName
addr.filename, addr.module)
File "/usr/local/lib/python3.6/site-packages/nose/importer.py", line 47, in importFromPath
return self.importFromDir(dir_path, fqname)
File "/usr/local/lib/python3.6/site-packages/nose/importer.py", line 94, in importFromDir
mod = load_module(part_fqname, fh, filename, desc)
File "/usr/local/lib/python3.6/imp.py", line 234, in load_module
return load_source(name, filename, file)
File "/usr/local/lib/python3.6/imp.py", line 172, in load_source
module = _load(spec)
File "<frozen importlib._bootstrap>", line 675, in _load
File "<frozen importlib._bootstrap>", line 655, in _load_unlocked
File "<frozen importlib._bootstrap_external>", line 678, in exec_module
File "<frozen importlib._bootstrap>", line 205, in _call_with_frames_removed
File "/usr/src/project/tests/package_test.py", line 2, in <module>
from package import Service
ImportError: cannot import name 'Service'
----------------------------------------------------------------------
Ran 1 test in 0.046s
FAILED (errors=1)
How do I import my package into my test class?
Do I have to make the project a module?
Do I have to package it for distribution with a setup.py
?
To solve your problem, you should change import to be full path, including module directory:
from package.package import Service
The reason because this works is how python loads modules:
Packages are a way of structuring Python’s module namespace by using “dotted module names”. For example, the module name A.B designates a submodule named B in a package named A. When importing the package, Python searches through the directories on sys.path looking for the package subdirectory.
So, in your project there is package
folder, which contains package.py
file. So in order python could find it, you have to provide full path.