我有一个程序可以在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框架。
答案 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'))