简体   繁体   中英

Python unittest with test/ and src/ not finding src modules

I have a simple directory structure:

proj/
    src/
        __init__.py
        foo.py
        bar.py
    test/
        __init__.py
        test_foo.py

test_foo.py

import unittest

import sys
sys.path.append('../src')

from src import foo

class TestFoo(unittest.TestCase):

  def test_foo(self):
    foo.start()


if __name__ == '__main__':
    unittest.main()

foo.py

import bar

def start():
  bar.do_stuff()

When running my test (I'm using vscode), I get the following error:

Failed to import test module: test_foo
Traceback (most recent call last):
  File "~/.pyenv/versions/3.8.6/lib/python3.8/unittest/loader.py", line 436, in _find_test_path
    module = self._get_module_from_name(name)
  File "~/.pyenv/versions/3.8.6/lib/python3.8/unittest/loader.py", line 377, in _get_module_from_name
    __import__(name)
  File "~/proj/test/test_foo.py", line 6, in <module>
    from src import foo
  File "~/proj/src/foo.py", line 1, in <module>
    import bar
ModuleNotFoundError: No module named 'bar'

I'm not sure why the test can't discover the src/bar when importing src/foo

Instead of import bar try from src import bar .

from src import bar


def start():
    bar.do_stuff()

Notice

Keep in mind, that you only adjusted the path in the test. You do not want the tests to work, but the application to fail because you forgot to adjust the path in the application at some point.

Two changes:

  1. from src import bar in foo.py ,

  2. before import modules in test_foo.py , add

     import sys sys.path.append("./")

Then you should be able to run code successfully.

在此处输入图片说明

In my case, I had imports of modules which are not actually installed, in my bar.py file, such as:

import requests

After installing those modules, VSCode showed tests properly.

What is in your bar.py file? Just the do_stuff() function? Or is the do_stuff() function a method of object bar ?

Depending on the answer to the question above, try doing something like this in your foo.py file:

from proj.src.bar import [name of function you're testing here]

In your specific case, it would be like this if do_stuff() is a standalone function:

from proj.src.bar import do_stuff

and then your foo.py file would be:

from proj.src.bar import do_stuff

def stuff():
  do_stuff()

However, if do_stuff() is a method of the bar object, it would probably be something like this, although it's hard to tell without knowing the contents of the bar.py file:

from proj.src.bar import bar

and then your foo.py file would be similar to the way you have it now:

from proj.src.bar import bar

def stuff():
  bar.do_stuff()

I recently ran into a similar problem when trying to import one neighboring file into another. This link helped me out, too.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM