2011-01-26 61 views
2

比方說,我有這樣一組代碼,它是一個長時間運行的執行線程,用於輪詢事件並引發其他事件(在我的情況下,使用XMLRPC調用)。它需要被重構爲乾淨的對象,所以它可以進行單元測試,但同時我想在某些集成測試中捕獲它的一些當前行爲,將它當作黑盒子對待。例如:在沒有修改的線程中測試Python代碼?

# long-lived code 
import xmlrpclib 
s = xmlrpclib.ServerProxy('http://XXX:yyyy') 
def do_stuff(): 
    while True: 
     ... 
     if s.xyz(): 
      s.do_thing(...) 

_

# test code 
import threading, time 
# stub out xmlrpclib 
def run_do_stuff(): 
    other_code.do_stuff() 

def setUp(): 
    t = threading.Thread(target=run_do_stuff) 
    t.setDaemon(True) 

def tearDown(): 
    # somehow kill t 
    t.join() 

def test1(): 
    t.start() 
    time.sleep(5) 
    assert some_XMLRPC_side_effects 

最後一個大的問題是,在測試的代碼被設計爲永遠運行,直到按Ctrl-C,我看不出有什麼辦法強迫它會引發異常或以其他方式殺死線程,因此我可以在不改變正在測試的代碼的情況下從頭啓動它。一旦我調用被測函數,我就失去了從線程輪詢任何標誌的能力。

我知道這是真的沒有如何設計測試工作,集成測試是有限的價值等,等等,但我希望通過輕柔工作向朋友展示測試和良好設計的價值而不是完全重新設計他的軟件。

回答

0

我想我找到了一個解決方案,可以完成我一直在尋找的任務:不使用線程,而是使用單獨的進程。

我可以編寫一個小型的python stub來模擬並以受控的方式運行代碼。然後,我可以編寫實際的測試,在每個測試的子進程中運行我的存根,並在每次測試完成後將其殺死。測試過程可以通過stdio或套接字與存根交互。

4

最後一個大的問題是,在測試的代碼被設計爲永遠運行,直到按Ctrl-C,我看不出有什麼辦法,迫使它拋出一個異常或以其他方式殺死線程

測試驅動開發的重點在於重新考慮您的設計,使其可測試。

循環永遠 - 雖然看起來很好的生產使用 - 是不可測的。

所以讓循環終止。它不會傷害生產。它會提高可測性。

「設計永遠運行」不是爲可測試性設計的。所以修復設計是可測試的。

+0

所有有效的點,但如果我正在尋找關於良好開發實踐的一般建議,我不會問這個關於物流的問題。 – 2011-04-01 18:28:39

相關問題