2016-10-06 60 views
3

我有一個程序可以與Linux交互並更改塊設備(/ dev/sda等)。我使用各種外部命令(主要是來自fdisk和GNU fdisk包的命令)來控制設備。我已經創建了一個類,它用作塊設備的大多數基本操作的接口(有關如下信息:它是多大的?它在哪裏安裝?等等)如何單元測試與塊設備交互的程序

下面是查詢一個分區:

def get_drive_size(device): 
    """Returns the maximum size of the drive, in sectors. 

    :device the device identifier (/dev/sda and such)""" 

    query_proc = subprocess.Popen(["blockdev", "--getsz", device], stdout=subprocess.PIPE) 
    #blockdev returns the number of 512B blocks in a drive 
    output, error = query_proc.communicate() 
    exit_code = query_proc.returncode 
    if exit_code != 0: 
     raise Exception("Non-zero exit code", str(error, "utf-8")) #I have custom exceptions, this is slight pseudo-code 

    return int(output) #should always be valid 

所以這個方法接受一個塊設備路徑,並返回一個整數。測試將以root用戶身份運行,因爲整個程序最終不得不以root用戶身份運行。

我應該嘗試和測試這些方法的代碼嗎?如果是這樣,怎麼樣?我可以嘗試爲每個測試創建和掛載圖像文件,但是這看起來像是很多開銷,並且可能本身就是容易出錯的。它期望塊設備,所以我不能直接操作文件系統中的圖像文件。

我可以嘗試嘲笑,如一些答案所示,但這種感覺不足。我似乎開始測試方法的實現,如果我嘲笑Popen對象,而不是輸出。在這種情況下,這是對正確的單元測試方法的正確評估嗎?

我對這個項目使用python3,我還沒有選擇單元測試框架。在沒有其他原因的情況下,我可能會使用Python中包含的默認單元測試框架。

回答

2

你應該看看模擬模塊(我認爲它現在是Python 3中的unittest模塊的一部分)。

它使您能夠運行測試,而不需要依賴任何外部資源,同時讓您控制模擬如何與您的代碼進行交互。

我會從文檔開始Voidspace

下面是一個例子:

import unittest2 as unittest 
import mock 

class GetDriveSizeTestSuite(unittest.TestCase): 

    @mock.patch('path/to/original/file.subprocess.Popen') 
    def test_a_scenario_with_mock_subprocess(self, mock_popen): 
    mock_popen.return_value.communicate.return_value = ('Expected_value', '') 
    mock_popen.return_value.returncode = '0' 
    self.assertEqual('expected_value', get_drive_size('some device')) 
+0

我用我的方法非Python命令。我如何模擬這些系統命令? – DonyorM

+0

你可以模擬subprocess.Popen,然後告訴它返回一個適合你想測試的場景的值。模擬的一點是,你不需要實際上與你正在測試的代碼以外的其他任何東西進行交互。你可以讓模擬返回你想要的任何輸出,甚至可以在調用時引發異常。 –

+0

我想這可以工作,雖然Popen對象沒有傳入方法。我將如何插入Popen模擬器?我不想讓它成爲一個參數,這會打破方法的目的。 – DonyorM

相關問題