如何对与块设备交互的测试程序进行单元测试

时间:2016-10-06 05:15:54

标签: python unit-testing

我有一个程序可以在linux上与块设备(/ dev / sda等)进行交互并进行更改。我正在使用各种外部命令(主要是来自fdisk和GNU fdisk包的命令)来控制设备。我创建了一个类作为块设备的大多数基本操作的接口(用于以下信息:它的大小是什么?它安装在哪里等等)

以下是查询分区大小的一种方法:

def get_drive_size(device):
    """Returns the maximum size of the drive, in sectors.

    :device the device identifier (/dev/sda and such)"""

    query_proc = subprocess.Popen(["blockdev", "--getsz", device], stdout=subprocess.PIPE) 
    #blockdev returns the number of 512B blocks in a drive
    output, error = query_proc.communicate()
    exit_code = query_proc.returncode
    if exit_code != 0:
        raise Exception("Non-zero exit code", str(error, "utf-8")) #I have custom exceptions, this is slight pseudo-code

    return int(output) #should always be valid

因此,此方法接受块设备路径,并返回一个整数。测试将以root身份运行,因为整个程序最终都必须以root身份运行。

我应该尝试测试这些方法之类的代码吗?如果是这样,怎么样?我可以尝试为每个测试创建和挂载图像文件,但这似乎是很多开销,并且本身可能容易出错。它需要块设备,因此我无法直接在文件系统中的图像文件上操作。

我可以尝试嘲笑,正如一些答案所暗示的那样,但这感觉不合适。看来我开始测试该方法的实现,如果我模拟Popen对象,而不是输出。在这种情况下,这是对正确的单元测试方法的正确评估吗?

我在这个项目中使用python3,我还没有选择单元测试框架。在没有其他原因的情况下,我可能会使用Python中包含的默认unittest框架。

1 个答案:

答案 0 :(得分:2)

您应该查看模拟模块(我认为它现在是Python 3中的unittest模块的一部分)。

它使您能够在不需要依赖任何外部资源的情况下运行测试,同时让您可以控制模拟与代码的交互方式。

我会从Voidspace

中的文档开始

以下是一个例子:

import unittest2 as unittest
import mock

class GetDriveSizeTestSuite(unittest.TestCase):

  @mock.patch('path/to/original/file.subprocess.Popen')
  def test_a_scenario_with_mock_subprocess(self, mock_popen):
    mock_popen.return_value.communicate.return_value = ('Expected_value', '')
    mock_popen.return_value.returncode = '0'
    self.assertEqual('expected_value', get_drive_size('some device'))