Ex52 import error, failed nosetest, app.py still runs in browser

I’m working on the final exercise, and have a strange issue. I have previously had difficulties with running nosetests. My file structure is the same as laid out in ex 52:

  • /gothonweb
    • __init__.py
    • app.py
    • markup.py
    • planisphere.py
    • /static
    • /templates
      • layout.html
      • show_room.html
      • you_died.html
    • /tests
      • app_tests.py
      • planisphere_tests.py

app.py runs just fine on localhost in the browser, but when nosetests run I get a failure. The import statements in planisphere_tests.py are taken directly from the exercise:

from nose.tools import *
from gothonweb.planisphere import *

Traceback is:

  File "/Users/Zeesy/hard_way/projects/gothonweb/app.py", line 3, in <module>
    import planisphere
ModuleNotFoundError: No module named 'planisphere'

When run with:

from nose.tools import *
import planisphere

Traceback is:

  File "/Users/Zeesy/hard_way/projects/gothonweb/tests/planisphere_tests.py", line 2, in <module>
    import planisphere
ModuleNotFoundError: No module named 'planisphere'

As mentioned, app.py runs the local server with no problems and the game works perfectly in the browser. What is going on here?

Planisphere is a file, is that the name of your class/module in the file also?

I’m under the impression that if planisphere is a python file, then it can be considered a module and imported. So, from gothonweb.planisphere import * would import any class/module inside planisphere.py

Room is the class inside planisphere.py. When I change the line to from planisphere import Room, I get an internal server error and the page will not load. The nosetest also fails with
ModuleNotFoundError: No module named 'planisphere'

Oh. Is it in the same directory as your test file?

See initial post above for directory structure.

  • app.py and planisphere.py are in ‘/’
  • planisphere_tests.py is in ‘/tests/’

Following the stackoverflow post, I tried:

import sys
sys.path.insert(0, '/')

inside planisphere_tests.py

This results in two errors in nosetests, including

ModuleNotFoundError: No module named 'planisphere'

The game still runs in the browser with these changes.

Try putting a copy of planisphere in the directory with the test file.

Nosetest will also be grumpy about files in separate directories.

Python always assumes an import is in the same directory. I believe the link explains that python will not import from outside the current directory.
I hope someone else can pop in and help. I know I couldn’t use pytest on files in a separate directories.

Here’s another link:

Nosetest is actually just a unittest with a fancy costume. Should work the same.

1 Like

I’m confused about this, because in ex47, ex48 and ex49 the tests are in a tests folder, and the files being tested are in a subdirectory also called ex49 etc. These nosetests pass despite the different directories and the program not running (see previous post)
ie:

ex47
    -- ex47
        -- __init__.py
        -- game.py
    -- tests
        -- __init__.py
        -- ex47_tests.py

What is the point of running a test if it passes when the program is broken, and fails when the program works?

AH! I was missing an __init__.py from my /tests directory. This is what makes it a package. Now running into other issues but at least the original import statements work.

So the original import statement inside planisphere.py:

from gothonweb.planisphere import *

works.

2 Likes

Good to know!
I thought the import just had to have the init.py.
Thanks for an excellent question!

Very good point. False positives are a test’s worse attribute.

I really wish Zed would rewrite this part of the book with unittest or better still, PyTest, as Nose is rubbish.

Depending on how much you want to stick to the book, you might want to swap out Nose now for PyTest.

Your tests/ directory is in gothonweb/ so you have a confusion about what goes where. The file you wrote is here:

gothonweb/tests/planisphere_tests.py

Your gothonweb code is here:

gothonweb/planisphere.py

Now, inside the tests file you are saying:

“Python, from where I live right now (gothonweb/tests), load the file gothonweb/planisphere.py.” That makes python look for:

gothonweb/tests/gothonweb/planisphere.py

The solution is to simply do this:

cd gothonweb
mv tests …
cd …

Now your tests are on the same level as gothonweb so the import should work.