Я пишу некоторые функции, используя 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)

Я ознакомился с тестовыми модулями paramiko, но они кажутся довольно сложными для моего варианта использования, и я не уверен, как их упростить.

4
Chris Sewell 28 Авг 2017 в 14:13

4 ответа

Лучший ответ

Чтобы ответить на мой собственный вопрос, я создал: https: // github. ком / chrisjsewell / атомно- HPC / дерево / ведущий / atomic_hpc / mockssh.

Как readme обсуждает; он основан на https://github.com/carletes/mock- ssh-server / tree / master / mockssh с добавлением (для реализации большего количества функций sftp) на основе https : //github.com/rspivak/sftpserver

Также были внесены следующие изменения:

  • измененный параметр users, так что можно использовать либо private_path_key, либо пароль
  • добавлен параметр dirname в диспетчер контекста Server, так что this будет задан в качестве корневого пути на протяжении контекста.
  • исправлено paramiko.sftp_client.SFTPClient.chdir, чтобы исправить его использование с относительными путями.

См. Test_mockssh.py для примера использования.

2
Chris Sewell 29 Авг 2017 в 15:03

Если вы хотите проверить удаленное подключение, структуру удаленной файловой системы и навигацию по удаленному пути, вам необходимо настроить фиктивный хост-сервер (возможно, виртуальную машину). Другими словами, если вы хотите проверить свои действия на хосте , вы должны смоделировать хост.

Если вы хотите проверить свои действия с данными хоста , кажется, что самый простой способ - выполнить running.t в другом ответе.

0
Hrabal 28 Авг 2017 в 11:43

Я согласен с HraBal из-за «Инфраструктура как код» . Вы можете рассматривать виртуальную машину как блок кода.

Например:

  1. Вы можете использовать vagrant или docker для инициализации сервера SSH, а затем и изменить свой файл конфигурации DNS. {{Х0}}
  2. положить приложение на сервер. и запустите paramiko для подключения target domain и проверьте, что вы хотите.

Я думаю, это то преимущество, что вы можете сделать это для всех языков программирования, и вам не нужно изобретать велосипед. Кроме того, вы и ваши преемники будут знать детали системы.

(Мой английский не очень хорош)

0
kyakya 4 Дек 2019 в 02:50

Я думаю, что вам действительно нужно высмеивать это paramiko.SSHClient объект. Вы проводите тестирование своей функции my_function, вы можете предположить, что модуль paramiko работает правильно, и единственное, что вам нужно для модульного тестирования, - это если my_function правильно вызывает методы этого paramiko.SSHClient ,

Для макета paramiko.SSH модуля вы можете использовать unittest.mock и украсьте вашу test_my_function функцию @mock.patch.object(paramiko.SSHClient, sshclientmock). Сначала вы должны определить sshclientmock как Mock или MagicMock.

Также в python 2.7 есть некоторый эквивалент unittest.mock, но я не помню, где его найти.

РЕДАКТИРОВАТЬ: Как @chepner упоминается в комментарии. Для python 2.7 вы можете найти модуль mock в pypi и установить это с помощью pip install mock

5
running.t 28 Авг 2017 в 12:03