简体   繁体   中英

Python library project structure best practice: imports and tests

I want to refactor a python library i am using a lot in my day to day work to publish it on github as open source. Before doing so, i would like to be compliant with some kind of best practice for python projects structure. I am going to describe below want i would like to do and i would appreciate your suggestions.

Here is my library (mylib) structure:

mylib/
   /examples/
       simple_example.py
   /mylib/
       __init__.py
       foo.py
       bar.py
   /tests/
       test_foo.py
       test_bar.py

Here are the files:

#foo.py
def Foo():
    print("foo.Foo")


#bar.py
import foo

def Bar():
    print("bar.Bar")
    foo.Foo()


#test_bar.py
from ..mylib import bar #doesnt work!

class TestBar(unittest.TestCase):
    def test_1(self):
        bar.Bar()
        self.assertEqual(True, True)

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


#simple_example.py
from .. import foo #doesnt work!
from .. import bar #doesnt work!

if __name__ == '__main__':  
    foo.Foo()
    bar.Bar()

What i would like to do is:

1- Execute simple_example.py ideally from /mylib/examples/:

$cd myapp
$cd examples
$python simple_example.py
Traceback (most recent call last):
  File "simple_example.py", line 2, in <module>
    from .. import foo
SystemError: Parent module '' not loaded, cannot perform relative import

2- Execute a single test file ideally from /mylib/tests/:

$cd myapp
$cd tests
$python test_bar.py
Traceback (most recent call last):
  File "test_bar.py", line 3, in <module>
    from ..mylib import bar
SystemError: Parent module '' not loaded, cannot perform relative import    

3- Execute all tests from mylib root

$cd myapp
$python -m unittest discover tests #same problem as above!

So, the problems are in the import statement in simple_example.py and test_bar.py. What is the best method to fix those imports?

Note that I would like to use python standard lib unittest for unit testing.

Thanks

Charlie

When running your test code, you want to do absolute imports. This is because when you're running unit tests, etc., you should assume your 'library' is installed in local development mode for testing -- don't use relative imports because you are not in the same package.

Here's how you would do an import in your test_foo.py file, for example:

# test_foo.py
from mylib.foo import Foo

# ... your test code here

In general, you should only use relative imports INSIDE of your library code, not in your tests =)

I hope this helps.

EDIT : You also need to install your library in development mode before this will work. You can do this in one of two ways:

$ python setup.py develop

OR

$ pip install -e .

Either of the above commands will inspect your project's setup.py file, which tells Python how your package is built / created, and will install it locally so you can run tests / mess with it.

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