2013-08-29 38 views
2

我有一個以迭代方式建立的對象。我想要測試每一個步驟。下面是一個不好的測試功能:在鼻測中分測試的正確方法

def test_object: 
    o = object.Object() 
    o.step1() # in place method 
    assert(o.step1property) 
    o.step2() # in place method 
    assert(o.step2property) 
    o.step3() # in place method 
    # ... 

所以,每走一步之後,我檢查對象是否有一些所需的性能,應該是有。我可以用yield關鍵字拆分到這個測驗,如:

def test_object: 
    o = object.Object() 
    yield o.step1 
    assert(o.step1property) 
    yield o.step2 
    # ... 

此時你可能會問:爲什麼不放在單獨的測試,這些電話?如果他們需要以前結果的正確輸出,請將其放在.pickle文件中並使其獨立於。我一般同意。然而,我有一個用例並不是非常有用:讓我們說step1()初始化類,而step2()是一個JSON導出。然後,我需要確保JSON導出始終可用,即使我在step1()中更改了內容。依賴.pickle文件會很危險,因爲它們可能已經過時了,並且JSON導出可能會通過,實際上它會導致我的最新對象失敗。我可以在兩個單獨的測試中分離斷言並運行兩次(一次在自己的測試中,一次在測試2的設置方法中),但step1()非常耗時。

這樣做的首選方式是什麼?有沒有辦法調用yield以外的「子測試」,我可以獲得這些子測試的返回值嗎?在我的情況下,我很想擁有JSON字符串,因爲我將所有測試結果保存到輸出目錄,並且我想將字符串傳遞給write_to_output_dir函數(如果這是不好的設計,請告訴我!)。

回答

2

如果一個類很難像這樣測試,那麼很有可能在面向對象的設計中做了一些不太理想的事情。如果你可以騰出時間看看this tech talk on unit testing。它還處理好(如可測試的)面向對象設計。從本質上講,最好讓你的單元測試儘可能原子化。此外,你可以模擬不相關的功能,而不是在特定的單元測試中測試。

專注於你的例子:你想獨立檢查初始化。我認爲這是一種工廠。然後你有一個方法導出到JSON。這可能就是您想要模擬您的初始化對象並在此模擬中測試JSON導出的關鍵。也就是說,JSON導出器也應該是一個獨立的類,以避免混合初始化和操作邏輯。一旦你重構了代碼,你可能會發現測試它更容易。

+0

我同意我的測試應該是原子性的。這就是說,即使前面的功能發生變化,JSON輸出也需要工作。我有一個函數可以根據工廠文件測試JSON導出,但是我也想根據當前版本的對象來測試它,而不必一直更新那個工廠文件(這很經常!)。關於單獨的類:爲了更好的可讀性,我保持上面的代碼簡單。我的代碼中真正的問題是如何在分測試中分割測試,因此只有對子測試的調用(在我的示例中使用yield)對我來說似乎很重要。 –

+0

(繼續以前的評論:)從你的答案我讀到,人們不會做一般的子測試。我會看看你鏈接的技術講座,希望它能幫助我更好地理解測試。感謝您的幫助! –