PYTHON: nosetests import file path with multiple m

2019-05-29 15:41发布

问题:

I'm currently working through LearnPythonTheHardWay and have reached Exercise 48 which details Nosetests. I am able to perform a unit testing as long as all of the code is in a single python.py file. However if I include other files as part of a program, i.e. use import and then attempt to nosetest such a project I am getting an error, as follows:

======================================================================

ERROR: Failure: ImportError (No module named 'temp')

Traceback (most recent call last):
File "/usr/local/lib/python3.4/dist-packages/nose/failure.py", line 39, in runTest
raise self.exc_val.with_traceback(self.tb)
File "/usr/local/lib/python3.4/dist-packages/nose/loader.py", line 414, in loadTestsFromName ## ##
addr.filename, addr.module)
File "/usr/local/lib/python3.4/dist-packages/nose/importer.py", line 47, in importFromPath
return self.importFromDir(dir_path, fqname)
File "/usr/local/lib/python3.4/dist-packages/nose/importer.py", line 94, in importFromDir
mod = load_module(part_fqname, fh, filename, desc)
File "/usr/lib/python3.4/imp.py", line 235, in load_module
return load_source(name, filename, file)
File "/usr/lib/python3.4/imp.py", line 171, in load_source
module = methods.load()
File "", line 1220, in load
File "", line 1200, in _load_unlocked
File "", line 1129, in _exec
File "", line 1471, in exec_module
File "", line 321, in _call_with_frames_removed
File "/home/user/LEARNPYTHONTHEHARDWAY/ex48/tests/scanner_tests.py", line 6, in
from ex48.scanner import lexicon
File "/home/user/LEARNPYTHONTHEHARDWAY/ex48/ex48/scanner.py", line 6, in
import temp
ImportError: No module named 'temp'


Ran 1 test in 0.028s

FAILED (errors=1)

The structure of my project directories are as follows:

ex48/
  ex48/
     scanner.py
     temp.py
  __pycache__/
  tests/
     __init__.py
    scanner_tests.py

Screenshot of my directory::

Screen shot of files themselves::

My scanner_tests.py file is as follows:

from nose.tools import *
from ex48.scanner import lexicon
from ex48 import temp

def test_directions():
    assert_equal(lexicon.scan("north"),[('direction','north')])
        result = lexicon.scan("north south east")
        assert_equal(result, [('direction', 'north'),
                          ('direction', 'south'),
                          ('direction', 'east')])

My scanner.py file is as follows:

   import temp

   class lexicon:
       def scan(val):
          if(val == "north"):
              return [('direction', 'north')]
          else:
              return [('direction', 'north'),
                      ('direction', 'south'),
                      ('direction', 'east')]

    runner = temp.temp("hello")

And finally my temp.py file is as follows:

   class temp(object):
       def __init__(self,name):
           self.name = name
       def run(self):
           print "Your name is; %s" % self.name     
    runner.run()

My question is how to overcome the ImportError: No Module named 'temp' because it seems as if I have imported the temp.py file in both the scanner.py file and the scanner_tests.py file but nose does not seem to be able to import it when it runs. Nosetests works fine when its just the single scanner.py file but not when importing. Is there a special syntax for importing into a unit test for nose? The script also works fine when run and imports properly at the command line.

*Note: I'm running python off a limited account off an online server so some admin privileges are not available.

**Note below are entirely different screenshots from another project with the exact same error:

Directory Layout:

Game.py:

Otherpy.py - the imported file:

the Nose test script file:

And finally the nosetests importerror:

回答1:

Everything needs to be with respect to your execution point. You are running your nose command from the root of ex48, therefore all your imports need to be with respect to that location.

Therefore, in game.py you should be importing with respect to ex48. Therefore:

from ex48.otherpy import House

The same logic should be applied to your example referencing the temp folder.

from ex48.temp import temp


回答2:

The only solution I have found is to post the following to the top of the main file:

try: 
     # This handles imports when running .py files from inside app directory
     from file_to_import.py import class_instance
except:
     # This handles imports when running nosetests from top-level (above app) 
     # directory
     from directory_containing_app_files.file_to_import import class_instance

I am supremely interested in an alternative solution.