2016-10-24 58 views
0

我試圖通過將測試放在與我的應用程序不同的目錄中來合理組織我的代碼。但是,對於測試,導入工作爲,其中爲應用程序,但不是兩者。下面是我的說明目前的問題一個人爲的例子:如下跨應用程序/測試導入python的更優雅的解決方案?

myapp/ 
    app/ 
    main.py 
    settings.py 
    moods.py 
    test/ 
    test_moods.py 

文件的內容:

main.py

import settings 
from moods import Moods 

words = Moods(settings.EXAMPLE) 
print(words.excited()) 

settings.py

EXAMPLE = "Wow$ Python$" 
DELIM = "$" 

moods.py

import settings 

class Moods: 
    def __init__(self, text): 
     self.text = text 

    def excited(self): 
     return self.text.replace(settings.DELIM, "!!!") 

test_moods.py

import sys, os, unittest 
sys.path.insert(0, os.path.abspath('..')) 

from app.moods import Moods 

class TestMood(unittest.TestCase): 
    def setUp(self): 
     self.words = Moods("Broken imports$ So sad$") 

    def test_mood(self): 
     self.assertEqual(self.words.excited(), "Broken imports!!! So sad!!!") 
     with self.assertRaises(AttributeError): 
      self.words.angry() 

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

在當前狀態下,從myapp/我可以運行成功如下:

>> python3 app/main.py 
Wow!!! Python!!! 

但是,當我嘗試運行測試,moods.py中的導入失敗:

>> python3 -m unittest discover test/ 
ImportError: Failed to import test module: test_moods 
[ stack trace here pointing to first line of moods.py ] 
ImportError: No module named 'settings' 

如果我將moods.py的第1行修改爲from app import settings,測試會通過,但應用程序的正常執行會失敗,因爲它看不到任何模塊app

我能想到的唯一解決方案是

  1. 把測試在同一目錄中的代碼(我試圖避免)
  2. 在我的應用程序,使添加sys.path.insert(0, os.path.abspath('..'))每個文件進口產品與測試產品一樣(這看起來很凌亂)

有沒有更優雅的方法來解決這個導入問題?

回答

2

您應該同時有apptest目錄中的PYTHONPATH

一種方法是替換此:

sys.path.insert(0, os.path.abspath('..')) 

from app.moods import Moods 

與此:

sys.path.insert(0, os.path.abspath('../app')) 

from moods import Moods 

或者你也可以運行測試之前設置PYTHONPATH environament變量。

爲什麼?因爲當你運行main.py時,那麼app是在路徑中,而不是app/..,所以你希望在運行測試時有相同的。

+0

嗯......到目前爲止,這個解決方案似乎是最有前途的。它很乾淨,並且保持對測試文件的路徑修改。但是,它不起作用。按照上面的建議實現代碼更改會產生:'ImportError:No module named'moods'' – vastlysuperiorman

+0

好的...奇怪的是,設置'os.path.abspath('app')'工作。我想這是因爲我從父目錄運行測試,它知道應用程序目錄? – vastlysuperiorman

+0

@vastlysuperiorman如果您從父目錄運行,那麼'app'是正確的路徑,是的。 – zvone

相關問題