Unittesting使用subprocess.Popen的Python代码

2024-05-14 00:17:21 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个Python项目,在这个项目中,我读取外部文件,处理它们,并将结果写入一个新文件。输入文件可以直接读取,也可以使用git show从git存储库中提取。调用git show并返回stdout的函数如下所示:

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版本,而且很可能是OS和要读取的实际文件。

我想为git_show()设置一个unittest,以便确保整个应用程序从输入到输出都能正常工作。然而,据我所知,如果没有一个真正的git存储库来测试,这是不可能的。整个包都是用git进行版本管理的,我希望如果我在git存储库中有一个git存储库,它可能会自己导致问题,而我脑海中的声音告诉我,这可能不是最好的解决方案。

如何最好地实现从git show(通常是命令行/Popen.communicate())获得输入的unittesting代码?


Tags: 文件项目gitshowstderrstdoutcoderev
2条回答

所以我的方法是用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

也许你想要(一种组合)不同类型的测试。

单元测试

在代码中测试代码的一小部分。

  1. 模拟subprocess.Popen
  2. stdout, stderr中返回静态值
  3. 检查处理是否正确

示例代码很小,您只能测试stdout是否真的返回,以及在非零wait()时是否引发异常。

介于两者之间

测试向量,即给定的集合输入,应该产生集合输出

  1. 模拟git,而是使用以特定方式编码的cat vector1.txt
  2. 试验结果

集成测试

测试代码如何连接到外部实体,在本例中为git。这样的测试可以防止您意外地改变内部系统的期望值。这就是“冻结”API。

  1. 创建一个带有小型git存储库的tarball
  2. 可选地将git二进制文件打包到同一个tarball中
  3. 打开皮球
  4. 运行git命令
  5. 将输出与预期比较

相关问题 更多 >