2017-08-23 1 views
1

J'ai une suite de tests e2e qui charge certains appareils dans la base de données en appelant un script côté serveur en utilisant une connexion SSH.Comment réutiliser la connexion ssh pendant toute la suite pytest

Je veux garder les appareils que je charge en local pour tester ceux qui en ont besoin. Je voudrais écrire un quelque chose de test comme

class ExampleTests(BaseTest): 
    def test_A(self): 
     load_fixture('TEST_A') 
     do_actual_test() 

    def test_B(self): 
     load_fixture('TEST_B') 
     do_actual_test() 

Dans ma méthode load_fixture la connexion SSH est faite et le script est exécuté sur le côté serveur. Si j'exécute toute la suite de tests, cela créera une nouvelle connexion SSH chaque fois que j'appelle la méthode load_fixture. Conceptuellement, c'est ce que je veux. Je ne veux pas charger tous mes appareils pour tous mes tests avant tout test. Je veux être capable de lancer des appareils quand j'en ai besoin. par exemple.

class ExampleTests(BaseTest): 
    def test_B(self): 
     user_a = load_user_fixture('username-A') 
     do_some_testing_on_user_a() 
     load_post_fixture_for_user(user_a, subject='subject-a') 
     do_tests_using_post() 

Dans ce test, il créerait également 2 connexions SSH.

Donc, ce que je veux arriver, c'est que la première fois que j'appelle la méthode load_fixture, elle crée la connexion mais la conserve pendant toute la durée de la suite de tests. Ou je crée une connexion avant que tout test s'exécute et puis utilise cette connexion chaque fois que je charge un appareil. Bien sûr, il devrait continuer à fonctionner quand je cours les tests sur plusieurs noyaux.

Ma fonction load_fixture ressemble à quelque chose comme:

def load_fixtures(connection_info, command, fixtures): 
    out, err, exit_code = run_remote_fixture_script(connection_info, command, fixtures) 

def run_remote_fixture_script(connection_info, command_name, *args): 
    ssh = SSHClient() 
    ssh.connect(...) 
    command = ''' 
     ./load_fixture_script {test_target} {command} {args}; 
    '''.format(
     test_target=connection_info.target, 
     command=command_name, 
     args=''.join([" '{}'".format(arg) for arg in args]) 
    ) 
    stdin, stdout, stderr = ssh.exec_command(command) 
    exit_code = stdout.channel.recv_exit_status() 
    ssh.close() 
    return stdout, stderr, exit_code 

Je veux aussi rouvrir la connexion automatiquement si pour une raison quelconque ferme la connexion.

+0

Juste pour le compte rendu: Je pense que l'étiquette * test unitaire * est erronée ici. Quelque chose qui fait des appels SSH n'est ** pas ** un test unitaire. La plupart des gens pensent que les «tests unitaires» fonctionnent en isolation ** complète **. – GhostCat

+1

Merci, je suis d'accord, j'ai changé les tags – Enermis

Répondre

0

Vous devez utiliser

@pytest.fixture(scope="module")

Garder la portée en tant que module gardera pour toute suite de tests.

et méthode finaliseur au sein de votre appareil

`def run_remote_fixture_script(connection_info, command_name, *args): 
    ssh = SSHClient() 
    ssh.connect(...) 
    command = ''' 
     ./load_fixture_script {test_target} {command} {args}; 
     '''.format(
    test_target=connection_info.target, 
    command=command_name, 
    args=''.join([" '{}'".format(arg) for arg in args]) 
) 
    stdin, stdout, stderr = ssh.exec_command(command) 
    exit_code = stdout.channel.recv_exit_status() 
    def fin(): 
    print ("teardown ssh") 
    ssh.close() 
    request.addfinalizer(fin) 
return stdout, stderr, exit_code 

S'il vous plaît excuser le formattage du code. Vous pouvez voir ce link pour plus de détails

Et vous appelez cet appareil comme

def test_function(run_remote_fixture_script) output = run_remote_fixture_script

Hope this helps. La méthode Finalizer sera appelée suite de fin de test, si scope est la méthode, elle sera appelée après la méthode

+2

Vous pouvez utiliser "scope = session" si vous avez plusieurs modules. –