2015-05-29 128 views
3

我有一個Python項目,在該項目中,我讀取外部文件,處理它們並將結果寫入新文件。輸入文件可以直接讀取,也可以使用git show從git存儲庫中提取。該函數調用git show和返回標準輸出看起來是這樣的:使用子進程的單元測試Python代碼.Popen

def git_show(fname, rev): 
    '''Runs git show and returns stdout''' 
    process = subprocess.Popen(['git', 'show', '{}:{}'.format(rev, fname)], 
           stdout=subprocess.PIPE, stderr=subprocess.PIPE) 
    stdout, stderr = process.communicate() 
    ret_code = process.wait() 
    if ret_code: 
     raise Exception(stderr) 
    return stdout 

我有一個測試程序的整個處理部分單元測試,即一切除了讀取和寫入文件。但是,我偶然發現了(並修正了)關於從git_show()返回的字符串編碼的問題,這取決於Python版本,很可能是操作系統和實際讀取的文件。

我想爲git_show()設置單元測試,這樣我就可以確保整個應用程序從輸入到輸出都能正常工作。不過,據我所知,這是不可能的,沒有一個實際的git存儲庫進行測試。整個軟件包是使用git進行版本管理的,我希望如果我在git存儲庫中有一個git倉庫,可能會導致問題,並且我腦子裏的聲音告訴我,這可能不是最好的解決方案。

如何才能最好地實現從0​​(和通常命令行/ Popen.communicate())得到輸入的單元測試代碼?

回答

0

所以我做到這一點的方法是用pytest

實施例:做作

from subprocess import Popen, PIPE 


def test(): 
    p = Popen(["echo", "Hello World!"], stdout=PIPE) 
    stdout, _ = p.communicate() 

    assert stdout == b"Hello World!\n" 

輸出:

$ py.test -x -s test_subprocess.py 
======================================= test session starts ======================================== 
platform linux2 -- Python 2.7.9 -- py-1.4.28 -- pytest-2.7.1 
rootdir: /home/prologic/work/circuits, inifile: 
plugins: cov 
collected 1 items 

test_subprocess.py . 

===================================== 1 passed in 0.01 seconds ===================================== 

或者使用標準庫unittest

例子:

#!/usr/bin/env python 


from unittest import main, TestCase 


from subprocess import Popen, PIPE 


class TestProcess(TestCase): 

    def test(self): 
     p = Popen(["echo", "Hello World!"], stdout=PIPE) 
     stdout, _ = p.communicate() 

     self.assertEquals(stdout, b"Hello World!\n") 


if __name__ == "__main__": 
    main() 

輸出:

$ python test_subprocess.py 
. 
---------------------------------------------------------------------- 
Ran 1 test in 0.001s 

OK 
+0

1。這是否需要「py.test」或「unittest」足夠? 2.您正在創建一個源自python文件的字符串。是否存在重要的編碼影響,或者你的例子中的''stdout.read()''是否肯定會返回完全相同的字符串/編碼,就好像你在具有相同字符串的文件上調用''git show'' ,不管文件如何保存? – cmeeren

+0

否; pytest不是必需的;你*可以*使用unittest。您將獲得Python 3.x中的字節和Python 2.x中的str(*相當於字節*); ''stdout''將包含''git show''的輸出 –

+0

謝謝,會測試一下並看看。這對Win/Mac/Linux是否正確,並且應該在所有三個方面都「回聲」? – cmeeren

3

也許你想(的組合之一)不同類型的測試

單元測試

測試代碼的一小部分,你的代碼中。在stdout, stderr

  • 檢查

    1. 模擬出subprocess.Popen
    2. 返回靜態值的處理是正確的

    示例代碼是非常小的,你只能測試真的返回stdout,並且在非-zero wait()引發異常。

    之間

    測試向量的東西,即給定的設定輸入時,設置輸出應該產生

    1. 模擬出GIT中,而是使用cat vector1.txt編碼在特定的方式
    2. 測試結果

    集成測試

    測試您的代碼如何連接到外部實體,在此例中爲git。這樣的測試可以防止您意外改變內部系統的期望。這就是「凍結」API。

    1. 創建壓縮包具有小git倉庫
    2. 任選包GIT中的二進制到同一壓縮包
    3. 解壓壓縮包
    4. 運行git命令
    5. 輸出與預期