Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/362.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 您将如何测试此功能?_Python_Unit Testing_Testing_Testability - Fatal编程技术网

Python 您将如何测试此功能?

Python 您将如何测试此功能?,python,unit-testing,testing,testability,Python,Unit Testing,Testing,Testability,假设我们有一个函数,它使用终端程序convert将图像转换为另一种格式。代码如下: def convert_image(src, dest=None, extension='jpg', quality=100): # Create default destination - same path just different extension if dest is None: dest = src.split('.')[0] + '.' + extension

假设我们有一个函数,它使用终端程序convert将图像转换为另一种格式。代码如下:

def convert_image(src, dest=None, extension='jpg', quality=100):

    # Create default destination - same path just different extension
    if dest is None:
        dest = src.split('.')[0] + '.' + extension

    try:
        subprocess.check_call(['convert', src, '-quality', quality, dest])
    except CalledProcessError:
        raise ImageException('convert', 'Could not convert image')

    return dest
现在我想测试这个函数,以验证它是否按预期工作

最直接的方法可能是只做一个单元测试,提供真实映像的路径,并验证是否使用正确的扩展创建了新映像。但问题是,很难知道创建的图像是否确实是在质量设置为正确值的情况下创建的,并且在测试函数中实际转换真实图像有点尴尬

如果我这样调用函数:

convert_image('/tmp/myimage.png')
我现在真正感兴趣的是,它从这个输入将这个数组作为输入发送到check_调用:

['convert', '/tmp/myimage.png', '-quality', 100, '/tmp/myimage.jpg']
如果是这样的话,我就知道函数在这个特殊情况下做的事情是正确的

因此,如果用于测试目的的函数在我测试时只返回这个数组,并且在我运行实际程序时只转换图像,这将非常方便

但是,在所有函数中使用if语句来告诉函数执行不同的测试操作可能并不好,如果我从来没有对测试函数使用check_调用,那么我甚至可能在代码中出现测试代码未检测到的语法错误

我正在寻找关于如何测试这段代码或如何重构代码以使其更易于测试的建议/讨论/提示。我对使用python转换图像的更好方法不感兴趣,这个问题纯粹是关于代码的可测试性


因此,如果您能够测试这个函数,您将如何做呢?

这里要做的是模拟convert实用程序。然后您可以在没有实际图像文件的情况下进行测试。您的测试将读取传递给模拟实用程序的内容

换句话说,您要测试实际“进程间通信”的结果


或者,正如Brad所建议的,模拟subprocess.check_调用,这似乎是一个更好的主意。

我认为您很聪明,可以断言正确的数组被发送到了
check_调用
,使其成为一个正确的单元测试(而不是同时测试转换应用程序)。要做到这一点,您需要截获通话以检查通话

下面详细介绍了实现这一点的一种方法(请注意,代码未经测试,但应该给出该技术的概念)。要做到这一点,首先将对
check\u call
的调用封装在一个单独的函数中,类似这样的函数(它现在调用
convert\u image
而不是
子进程。check\u call
):

然后,在测试中,您可以用一个不同的函数替换
check\u call
,该函数断言将传递给
子流程的参数。check\u call
。下面显示了测试的示例:

import unittest

class ConvertImageTest(unittest.TestCase):

    def test_convert_image(self):

        # Test version of check_call to do the assertion
        def assert_check_call(args):
            expected = ['convert', '/tmp/myimage.png', '-quality', 100, '/tmp/myimage.jpg']
            self.assertEquals(expected, args)

        # Replace check_call with our test version
        my.module.check_call = assert_check_call

        # Perform the test
        convert_image('/tmp/myimage.png')
使用这种方法,模拟抛出的异常并测试如何响应也很简单


一个潜在的陷阱-您可能必须反向分配
my.module。事后检查调用
-老实说,不确定这是否是必需的(我想这取决于模块是否在测试之间重新导入,我们希望这是真的)。

您可以模拟对子流程的调用。检查调用吗?函数应该接受您正在传递的值,并在通过或失败时返回有意义的值?是的,我能。这绝对是一个合理的解决方案。很好的答案,这正是我想要的
import unittest

class ConvertImageTest(unittest.TestCase):

    def test_convert_image(self):

        # Test version of check_call to do the assertion
        def assert_check_call(args):
            expected = ['convert', '/tmp/myimage.png', '-quality', 100, '/tmp/myimage.jpg']
            self.assertEquals(expected, args)

        # Replace check_call with our test version
        my.module.check_call = assert_check_call

        # Perform the test
        convert_image('/tmp/myimage.png')