3

I'm trying to use nosetests to run my tests in a directory structure like this

src
    - file1.py
    - ...
test
    - helper.py
    - test_file1.py

As you can see, test_file1.py has some functions that test file1.py, so it imports file1.py like this:

# In file1.py
import file1
import helper

# Tests go here...

I also use a helper.py file that has some neat functionality built in so that I can create tests more easily. This functionality is achieved by extending a couple of classes in my actual code and overriding some methods. So helper.py looks something like this:

# In helper.py 
import file1

# Use stuff in file1.py

I'm having trouble understanding how nose goes about importing these things with its custom importer. I was able to get my test file to import file1.py by running nosetest ../tests within the src directory, but I'm currently getting an error akin to:

File helper.py:
ImportError: cannot import name file1 

How does nose do its imports and is there a way I can essentially get it to lump all my tests/src files together so they can all import one another while I keep them in separate folders?

ImpGuard
  • 885
  • 2
  • 13
  • 18
  • Use `import src.file1` in `header.py` or move entire `test` folder under `src` – J0HN Oct 03 '14 at 08:22
  • First option does not work. The second does not work as well. It seems that the actual test file `test_file1.py` can import `file1.py` but the helper file that IT imports cannot. – ImpGuard Oct 03 '14 at 09:01
  • 1
    Just one stupid question. Why do you import them as `file1.py`, not `file1`? – J0HN Oct 03 '14 at 09:14
  • Ah, sorry, that's just a typo here. I'll fix that! – ImpGuard Oct 03 '14 at 18:17

2 Answers2

2

Seeing that you execute tests with nosetests ../tests I assume they are executed from the tests folder itself. Therefore, files from the src directory are not added to sys.path, hence the error.

To fix this one could:

  • run tests from the parent directory - nosetests will be able to identify src and test (or tests) directory by himself and will add them to the sys.path before running tests

  • add src directory path to the PYTHONPATH before running nosetests (export PYTHONPATH=../src; nosetests)

Note that you can as well omit the last argument to the nosetests as by default it runs the tests from current directory. Otherwise, if the tests are not in the directory you launch nosetests from, you can define its location with --where=<path-to-tests> parameter (or, simply -w). So for example you can execute tests from src direcotory and without even setting the PYTHONPATH (because current directory will be added to sys.path by default) like this: nosetests -w ../tests.


Lastly, even though this is very questionable by itself, and yet: the most common way to organize a Python source code is having python files and packages starting directly in the project directory, and having tests in "test" sub-packages of the packages they test. So, in your case it would be:

/file1.py
/test/helper.py
/test/test_file1.py

or better:

/myproject/__init__.py
/myproject/file1.py
/myproject/test/__init__.py
/myproject/test/helper.py
/myproject/test/test_file1.py

(latter, provided you also use correct imports in your test sources, e.g. from .. import file1).

In which case one runs tests from the project's root directory simply with nosetests without any argument.

Anyway, nosetests is flexible enough to work with any structure - use whatever seems more suitable for you and the project.

More on project structure in What is the best project structure for a Python application?

Community
  • 1
  • 1
Tim
  • 12,318
  • 7
  • 50
  • 72
  • Thanks. Your first suggestion was how I assumed nosetest to work after reading documentation. However, the problem arises when tests in my `tests` directory import other test fixtures/files and src files. Nosetests gets confused and will either let me import other test modules OR let me import src files but not both. – ImpGuard Nov 05 '14 at 19:52
  • Yep, that's the point - normally, nosetests will let you do that if you run them from the directory parent to both 'src' and 'test'. In this case nosetests will add both to the sys.path and one is normally able to import sources from tests AND tests from other tests. In any case if this is still not working - I suggest printing out sys.path from various tests and examining it for "anomalies". And, worse case scenario, can export PYTHONPATH to enforce certain directories to be added to sys.path then. (Though, I think more proper way is yet to have a direcotry structure whic is good for nose). – Tim Nov 06 '14 at 06:45
  • The second bullet point, "export PYTHONPATH=./" solved my issue, now sub directories can 'see' each other when nosetests is run. – Rickka Aug 24 '17 at 13:39
0

This seems generally like an issue I had with nose tests:

Importing with Python and Nose Tests

The work around I found was to insert a try..except block so that BOTH python and nosetest commands will work on the same directory as follows:

(1) In your main file, at the very top before anything else add:

# In file1.py
   try:
       # This will allow you to do python file1.py inside the src directory
       from file2 import *
       from helper import *
   except:
       # This will allow you to run nosetests in the directory just above
       # the src and test directories.
       from src.file1 import *
       from src.helper import *

(2) Inside your test.py file add:

  from src.file2 import *
  from src.helper import * 
Community
  • 1
  • 1
Jeeves
  • 424
  • 1
  • 7
  • 25