用 Python 模拟远程主机

Chr*_*ell 4 python unit-testing mocking remote-server paramiko

我正在使用 paramiko 编写一些函数来执行命令并在远程主机上创建文件。我想为他们编写一些单元测试,但我不知道实现这一目标的最简单方法是什么?这是我设想的代码示例大纲:

import os
import paramiko
import pytest

def my_function(hostname, relpath='.', **kwargs):
    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    ssh.connect(hostname, **kwargs)
    sftp = ssh.open_sftp()
    sftp.chdir(relpath)
    stdin, stdout, stderr = ssh.exec_command("echo hallo > test.txt")

@pytest.fixture("module")
def mock_remote_host():
    # start a remote host here with a local test path
    try:
        yield hostname, testpath, {"username":"bob", "password":"1234"}
    finally:
        # delete the test path
        # close the remote host

def test_my_function(mock_remote_host):
    hostname, dirpath, kwargs = mock_remote_host
    my_function(hostname, **kwargs)
    filepath = os.path.join(dirpath, 'test.txt')
    assert os.path.exists(filepath)
Run Code Online (Sandbox Code Playgroud)

看过 paramiko 测试模块,但对于我的用例来说,它们似乎很复杂,我不知道如何简化它们。

run*_*g.t 5

我认为你真正需要嘲笑的是paramiko.SSHClientobject. 您正在对您的函数进行单元测试my_function,您可以假设paramiko模块正常工作,并且您唯一需要进行单元测试的是是否以正确的方式my_function调用此paramiko.SSHClient方法。

要模拟paramiko.SSH模块,您可以使用unittest.mock并使用.mock装饰您的test_my_function函数@mock.patch.object(paramiko.SSHClient, sshclientmock)。你必须定义sshclientmock为某种MockMagicMock第一。

同样在python 2.7中有一些等价物,unittest.mock但我不记得在哪里可以找到它。

编辑:正如@chepner 在评论中提到的那样。对于python 2.7,您可以mockpypi中找到模块并使用pip install mock


Chr*_*ell 2

为了回答我自己的问题,我创建了:https://github.com/chrisjsewell/atomic-hpc/tree/master/atomic_hpc/mockssh

正如自述文件所讨论的那样;它基于https://github.com/carletes/mock-ssh-server/tree/master/mockssh并在https://github.com/rspivak/sftpserver的基础上进行了添加(以实现更多 sftp 功能)

还进行了以下更改:

  • 修改users参数,以便可以使用 private_path_key 或密码
  • 向上下文管理器添加了一个dirname参数Server,以便将 this 设置为上下文持续时间内的根路径。
  • 修补paramiko.sftp_client.SFTPClient.chdir以修复其与相对路径的使用。

有关示例用途,请参阅 test_mockssh.py。