2015-05-29 129 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. 输出与预期