2014-01-10 59 views
0

我有一個我正在測試的Python模塊,並且由於模塊工作的方式(它在導入時會進行一些初始化)已在每個unittest期間重新加載模塊,初始化。 reloadsetUp方法中完成,所以所有的測試實際上是重新加載模塊,這很好。保存重新加載的Python模塊用於測試目的

如果我只在任何給定的Python會話期間在該文件中運行測試,這一切都很好,因爲我從不需要對模塊的前一個實例的引用。但是當我使用Pydev或unittestdiscover時,我得到的錯誤與here一樣,因爲導入此模塊的其他測試已經失去了對模塊中對象的引用,因爲它們是在測試中的所有重新加載業務之前導入的。

也有類似的問題,比如this one,但這些都是在重新加載後處理更新對象。我想要做的是在初始導入之後保存模塊的狀態,運行我的測試來完成所有重新加載,然後在測試tearDown中將模塊的初始引用放回,以便下游運行的測試使用該模塊仍然有正確的參考。請注意,我沒有對模塊進行任何更改,我只是重新加載它來測試它所做的一些初始化部分。

還有一些解決方案在模塊代碼中包含鉤子,我不感興趣。我不想要求開發人員將代碼推入代碼庫,以便測試可以運行。我正在使用Python 2.6和unittest。我發現有些項目的存在類似process-isolation,儘管我不確定這是否完全符合我的要求,但它不適用於Python 2.6,並且我不想在可能的情況下將新包添加到我們的堆棧。存根編號如下:

import mypackage.mymodule 
saved_module = mypackage.mymodule 

class SomeTestThatReloads(unittest.TestCase): 
    def setUp(self): 
     reload(mypackage.mymodule) 

    def tearDown(self): 
     # What to do here with saved_module? 

    def test_initialization(self): 
     # testing scenario code 

回答

0

不幸的是,沒有簡單的方法來做到這一點。如果你的模塊的初始化有副作用(並且看起來它有 - 掛鉤等),那麼沒有自動的方法來撤銷它們,而不是完全重新啓動Python進程。

同樣,如果任何事情在你的代碼進口的東西從你的模塊,而不是模塊本身(以下EG from my_package.my_module import some_object代替import my_package.my_module),重裝模塊將不會做任何事情來導入對象(some_object將把任何my_package.my_module.some_object簡稱當執行import語句時,無論您重新加載什麼以及磁盤上有什麼)。

所有問題都歸結爲Python的模塊系統通過執行模塊(其中充滿了副作用,類/函數/變量的定義只是其中的一個),然後暴露頂層他們創建的變量,而Python VM本身將模塊視爲全局狀態的一大塊,沒有隔離。

因此,您的問題,一般的解決方法是每次測試後重新啓動一個新的Python進程(很爛:()。

如果你的模塊的初始化副作用是有限的,你可以嘗試運行測試鼻子而不是單元測試(測試是兼容的,你不必重寫任何東西),其Isolate插件試圖做你想做的:http://nose.readthedocs.org/en/latest/plugins/isolate.html

但它不能保證在一般情況下工作,因爲我如上所述。