2017-08-28 4 views
1

J'écris certaines fonctions, en utilisant paramiko, pour exécuter des commandes et créer des fichiers sur un hôte distant. Je voudrais écrire quelques tests unitaires pour eux, mais je ne sais pas ce qui serait le moyen le plus simple pour y parvenir? Voilà ce que j'envisage comme un aperçu exemple de mon code:Mock un hôte distant en Python

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) 

J'ai eu un coup d'oeil à la paramiko test modules, mais ils semblent assez complexes pour mon cas d'utilisation et je ne suis pas sûr de savoir comment s'y prendre pour simplifier leur.

Répondre

1

Pour répondre à mes questions, j'ai créé: https://github.com/chrisjsewell/atomic-hpc/tree/master/atomic_hpc/mockssh.

En tant que readme discute; il est basé sur https://github.com/carletes/mock-ssh-server/tree/master/mockssh avec des additions faites (pour mettre en œuvre plus de fonctions SFTP) basée sur https://github.com/rspivak/sftpserver

Les modifications suivantes ont été apportées:

  • révisé paramètre users, de sorte que ce soit un private_path_key ou mot de passe peuvent être utilisés
  • a ajouté un paramètre dirname au gestionnaire de contexte Server, de sorte que ceci sera défini en tant que chemin racine pour la durée du contexte.
  • corrigé paramiko.sftp_client.SFTPClient.chdir pour fixer son utilisation avec des chemins relatifs.

Voir test_mockssh.py pour des exemples d'utilisation.

2

Je pense que ce dont vous avez vraiment besoin de se moquer est l'objet paramiko.SSHClient. Vous êtes unittesting votre fonction my_function, vous pouvez supposer paramiko module fonctionne correctement et la seule chose dont vous avez besoin pour tester un appareil est si my_function appelle les méthodes de ce paramiko.SSHClient de manière correcte.

Pour simuler le module paramiko.SSH, vous pouvez utiliser unittest.mock et décorer votre test_my_function avec @mock.patch.object(paramiko.SSHClient, sshclientmock). Vous devez d'abord définir sshclientmock comme une sorte de Mock ou MagicMock.

Aussi en python 2.7 il y a un équivalent de unittest.mock mais je ne me souviens pas où le trouver exactement.

EDIT: Comme @chepner mentionné dans le commentaire. Pour python 2.7, vous pouvez trouver mock module pypi et l'installer à l'aide pip install mock

+1

Le troisième module 'mock', disponible sur PyPi, est ce qui a été incorporé dans Python 3.3 sous le nom' unittest.mock'. – chepner

+0

Le seul problème que je vois avec cela, c'est que je vais utiliser beaucoup de fonctionnalités de paramiko pour créer/détruire des fichiers/dossiers etc Donc, cela signifie que je dois créer une fonction fictive pour tout le monde de ces fonctions.Ce qui vous donne l'impression de ne pas tester correctement ce qui va se passer dans le code de production. –

0

Si vous souhaitez tester la connectivité à distance, la structure du système de fichiers à distance et la navigation de chemin à distance, vous devez mettre en place un serveur hôte simulé (une machine virtuelle peut-être). En d'autres termes, si vous voulez tester vos actions sur l'hôte vous devez vous moquer de l'hôte.

Si vous voulez tester vos actions avec les données de l'hôte la manière la plus simple semble se poursuivre comme running.t dit dans l'autre réponse.

+0

yeh Je comprends ce que vous voulez dire, je suis juste fatigué que je finirai par écrire beaucoup de fonctions fictives, qui pourraient ne pas imiter complètement les fonctions réelles de paramiko, et donc je vais finir avec une suite de tests qui passe, mais j'échouerai quand j'essayerai de l'utiliser avec le vrai –

+0

J'ai eu le même problème en utilisant paramiko, je me suis moqué de la sortie de paramiko et tout allait bien, puis avec la vraie connexion sftp j'ai dû refaire beaucoup de code. La gestion de 'cwd' de Paramiko peut être parfois difficile (si vous' chdir' beaucoup). Je sais que c'est compliqué de construire un faux serveur sftp, mais si vous avez beaucoup d'actions sftp différentes dans votre application, cela en vaut vraiment la peine. – Hrabal