2016-08-04 22 views
3

Ich möchte eine Python-Bibliothek umgestalten Ich benutze viel in meinem täglichen Arbeit, um es auf Github als Open Source zu veröffentlichen. Bevor ich dies tue, möchte ich mit einer Art Best Practice für die Struktur von Python-Projekten konform gehen. Ich werde unten beschreiben möchte ich möchte tun, und ich würde Ihre Vorschläge zu schätzen wissen.Python Bibliothek Projektstruktur Best Practice: Importe und Tests

Hier ist meine Bibliothek (mylib) Struktur:

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

Hier sind die Dateien:

#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() 

Was ich tun möchte:

1- Execute simple_example.py idealerweise von/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- eine einzige Testdatei ausführen idealerweise von/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- alle Tests von mylib Wurzel

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

So ausführen, sind die Probleme in der Import-Anweisung in simple_example .py und test_bar.py. Was ist die beste Methode, um diese Importe zu beheben?

Beachten Sie, dass ich Python Standard Lib Unittest für Unit-Tests verwenden möchte.

Dank

Charlie

Antwort

1

Wenn Ihre Testcode ausgeführt wird, möchten Sie absolute Importe tun. Dies liegt daran, dass Sie beim Ausführen von Komponententests usw. davon ausgehen sollten, dass Ihre 'Bibliothek' zum Testen im lokalen Entwicklungsmodus installiert ist. Verwenden Sie keine relativen Importe, da Sie nicht im selben Paket sind.

Hier ist, wie Sie einen Import in Ihrer test_foo.py Datei tun würden, zum Beispiel:

# test_foo.py 
from mylib.foo import Foo 

# ... your test code here 

Im Allgemeinen Sie nur relative Importe INSIDE Ihre Bibliothek Code verwenden sollen, nicht in Ihren Tests =)

Ich hoffe, das hilft.

BEARBEITEN: Sie müssen auch Ihre Bibliothek im Entwicklungsmodus installieren, bevor dies funktioniert. Sie können in einer von zwei Möglichkeiten:

$ python setup.py develop 

ODER

$ pip install -e . 

Entweder der oben genannten Befehle Ihres Projekts setup.py Datei überprüfen, die Python sagt, wie Sie Ihr Paket gebaut wird/erstellt, und wird Installieren Sie es lokal, damit Sie Tests ausführen können.

+0

kann etwas fehlen (z. B. sys.path optimieren), aber mit Ihrer Lösung bekomme ich immer noch einen Fehler 'ImportError: Kein Modul namens mylib.foo' – Charlie

+0

Sie müssen zuerst Ihre Bibliothek im Entwicklungsmodus installieren. Sie müssen 'python setup.py develop 'ausführen, bevor Sie irgendwelche Tests ausführen. Ich werde meine Antwort aktualisieren, um dies zu reflektieren. – rdegges

+0

gerade versucht und es funktioniert! – Charlie