Nosetests Import Error

2019-07-23 11:48发布

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?

2条回答
Rolldiameter
2楼-- · 2019-07-23 12:20

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 * 
查看更多
男人必须洒脱
3楼-- · 2019-07-23 12:27

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?

查看更多
登录 后发表回答