Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django finds tests but fail to import them

I am getting weird errors, where a call to ./manage.py test will find my tests but complain that they cannot be imported.

Versions

Python 3.4

Django 1.7b4

My file structure

looks like this (just the relevant bits):

inkasso
├── db.sqlite3
├── functional_tests
│   ├── base.py
│   ├── base.pyc
│   ├── __init__.py
│   ├── __init__.pyc
│   ├── __pycache__
│   ├── test_login.py
│   └── test_login.pyc
├── __init__.py
├── inkasso
│   ├── __init__.py
│   ├── __init__.pyc
│   ├── migrations
│   ├── models.py
│   ├── settings.py
│   ├── settings.pyc
│   ├── urls.py
│   └── wsgi.py
├── manage.py
├── static
│   ├── ...
├── templates
│   ├── ...
└── web
    ├── admins.py
    ├── tests
    │   ├── __init__.py
    │   ├── test_forms.py
    │   ├── test_models.py
    │   └── test_views.py
    ├── urls.py
    └── views.py

The stack-trace

So when I run ./manage.py test I get the following stak-trace:

 $ ./manage.py test
Creating test database for alias 'default'...
EEEE
======================================================================
ERROR: inkasso.functional_tests.test_login (unittest.loader.ModuleImportFailure)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python3.4/unittest/case.py", line 57, in testPartExecutor
    yield
  File "/usr/lib/python3.4/unittest/case.py", line 574, in run
    testMethod()
  File "/usr/lib/python3.4/unittest/loader.py", line 32, in testFailure
    raise exception
ImportError: Failed to import test module: inkasso.functional_tests.test_login
Traceback (most recent call last):
  File "/usr/lib/python3.4/unittest/loader.py", line 312, in _find_tests
    module = self._get_module_from_name(name)
  File "/usr/lib/python3.4/unittest/loader.py", line 290, in _get_module_from_name
    __import__(name)
ImportError: No module named 'inkasso.functional_tests'


======================================================================
ERROR: inkasso.web.tests.test_forms (unittest.loader.ModuleImportFailure)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python3.4/unittest/case.py", line 57, in testPartExecutor
    yield
  File "/usr/lib/python3.4/unittest/case.py", line 574, in run
    testMethod()
  File "/usr/lib/python3.4/unittest/loader.py", line 32, in testFailure
    raise exception
ImportError: Failed to import test module: inkasso.web.tests.test_forms
Traceback (most recent call last):
  File "/usr/lib/python3.4/unittest/loader.py", line 312, in _find_tests
    module = self._get_module_from_name(name)
  File "/usr/lib/python3.4/unittest/loader.py", line 290, in _get_module_from_name
    __import__(name)
ImportError: No module named 'inkasso.web'


======================================================================
ERROR: inkasso.web.tests.test_models (unittest.loader.ModuleImportFailure)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python3.4/unittest/case.py", line 57, in testPartExecutor
    yield
  File "/usr/lib/python3.4/unittest/case.py", line 574, in run
    testMethod()
  File "/usr/lib/python3.4/unittest/loader.py", line 32, in testFailure
    raise exception
ImportError: Failed to import test module: inkasso.web.tests.test_models
Traceback (most recent call last):
  File "/usr/lib/python3.4/unittest/loader.py", line 312, in _find_tests
    module = self._get_module_from_name(name)
  File "/usr/lib/python3.4/unittest/loader.py", line 290, in _get_module_from_name
    __import__(name)
ImportError: No module named 'inkasso.web'


======================================================================
ERROR: inkasso.web.tests.test_views (unittest.loader.ModuleImportFailure)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python3.4/unittest/case.py", line 57, in testPartExecutor
    yield
  File "/usr/lib/python3.4/unittest/case.py", line 574, in run
    testMethod()
  File "/usr/lib/python3.4/unittest/loader.py", line 32, in testFailure
    raise exception
ImportError: Failed to import test module: inkasso.web.tests.test_views
Traceback (most recent call last):
  File "/usr/lib/python3.4/unittest/loader.py", line 312, in _find_tests
    module = self._get_module_from_name(name)
  File "/usr/lib/python3.4/unittest/loader.py", line 290, in _get_module_from_name
    __import__(name)
ImportError: No module named 'inkasso.web'


----------------------------------------------------------------------
Ran 4 tests in 0.001s

FAILED (errors=4)
Destroying test database for alias 'default'...

So the test runner finds my tests, but for some reason, they are not imported. I have no idea what it is going on. The stack-trace is not very helpful to me :(

Since the root folder is called inkasso and it has a module of the same name, I tried putting print(os.getcwd) and print(sys.path) into manage.py, and all it showed was that CWD and path was both set to point at the root folder, so it should be all good, no? The app itself runs as expected. It is only the tests that are not working.

For giggles, I tried creating an empty module 'web' in inkasso.inkasso, with the result that instead of complaining that inkasso.web doesn't exist, it now complains that inkasso.web.tests does not exist. So this shows that instead of looking in the root 'inkasso' folder, it looks in 'inkasso.inkasso'. So that is the issue. How can I fix it?

like image 807
Eldamir Avatar asked May 25 '14 11:05

Eldamir


1 Answers

Yeah... there's a problem with running ./manage.py, in that it adds the current directory to the PYTHONPATH.

This problem happens when you put an __init__.py inside the root folder.

One solution would be, in this case, to never use manage.py, but only django-admin.py <commands> --settings=inkasso.inkasso.settings - of course, this assumes either that when running this command, you're one level up, outside your root folder inkasso, or you have your main package installed in site-packages.

For example, if the complete path to your settings.py file is /home/user/projects/inkasso/inkasso/settings.py, you need to be in /home/user/projects when running this command.

If however you've got your package installed inside your site-packages, the above restriction changes: you can be anywhere except /home/user/projects/inkasso or any of its subfolders or so on.

Another solution is to edit your manage.py file to add this line:

if __name__ =='__main__': #line already present
    #this will make the python interpreter see your packages as inkasso.inkasso.whatever
    os.chdir('..')  # <<<---This is what you want to add

    os.environ.setdefault("DJANGO_SETTINGS_MODULE", "mvod.dev_settings")
    ....
like image 105
vlad-ardelean Avatar answered Sep 30 '22 17:09

vlad-ardelean