本文介绍了使用子进程的单元测试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()设置一个单元测试,以便确保从输入到输出,整个应用程序都能正常工作.但是,据我所知,如果没有实际的git存储库进行测试,这是不可能的.整个软件包都是使用git版本管理的,我希望,如果我在git存储库中有一个git存储库,这可能会独自导致问题,而我的脑海里却会告诉我这可能不是最好的解决方案. /p>

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

解决方案

也许您想要(多种测试的组合之一).

单元测试

在代码中测试一小部分代码.

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

示例代码非常小,您只能测试stdout是否真正返回,并且在wait()非零时会引发异常.

介于两者之间

给定设置输入的测试向量,应生成设置输出

  1. 模拟git,改为使用以特定方式编码的cat vector1.txt
  2. 测试结果

集成测试

测试您的代码如何连接到外部实体(在本例中为git).这样的测试可以防止您意外更改内部系统的期望.那就是冻结" API.

  1. 用一个小的git仓库创建一个tarball
  2. 还可以将git二进制文件打包到同一tarball中
  3. 打开压缩包的包装
  4. 运行git命令
  5. 将输出与预期进行比较

I have a Python project in which I read external files, process them, and write the results to a new file. The input files can either be read directly, or extracted from a git repository using git show. The function to call git show and return stdout looks like this:

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

I have unittests which test the whole processing part of the program, i.e., everything apart from reading and writing the files. However, I have stumbled upon (and fixed) issues regarding the encoding of the returned string from git_show(), depending Python version, and quite possibly OS and the actual file to read.

I would like to set up a unittest for git_show() so I can make sure the whole application works, from input to output. However, as far as I know, this is not possible without having an actual git repository to test on. The whole package is version managed with git, and I expect that if I have a git repository inside a git repository that might lead to problems on its own, and a voice in my head tells me that might not be the best solution anyway.

How can one best achieve unittesting code which gets input from git show (and in general, the command line / Popen.communicate())?

解决方案

Perhaps you want (one of combination of) different kinds of tests.

Unit tests

Test a small part of your code, within your code.

  1. mock out subprocess.Popen
  2. return static values in stdout, stderr
  3. check that processing is correct

Sample code is pretty small, you can only test that stdout is really returned and that upon non-zero wait() an exception is raised.

Something in between

Test vectors, that is given set input, set output should be produced

  1. mock out git, instead use cat vector1.txt encoded in specific way
  2. test result

Integration tests

Test how your code connects to external entities, in this case git. Such tests protects you from accidentally changing the expectation of the internal system. That is it "freezes" the API.

  1. create a tarball with a small git repository
  2. optionally pack git binary into same tarball
  3. unpack the tarball
  4. run git command
  5. compare output to expected

这篇关于使用子进程的单元测试Python代码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-27 08:25