如何在整个pytest套件中重用ssh连接

时间:2017-08-23 12:09:49

标签: ssh integration-testing pytest e2e-testing

我有一个e2e测试套件,它通过使用SSH连接调用服务器端的脚本来加载数据库中的一些装置。

我想保持我加载本地的灯具以测试需要它们。我会写一个类似

的测试
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()

在我的load_fixture方法中建立了SSH连接,脚本在服务器端运行。 如果我运行整个测试套件,每次调用load_fixture方法时都会创建一个新的SSH连接。从概念上讲,这就是我想要的。在任何测试运行之前,我都不想为我的所有测试加载所有的灯具。我希望能够在需要时运行灯具。 e.g。

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()

在此测试中,它还会创建2个ssh连接。

所以我想要发生的是我第一次调用load_fixture方法创建连接但在测试套件的持续时间内保持连接。或者我在任何测试运行之前创建一个连接,然后每当我加载一个fixture时使用该连接。 当然,当我在多核上运行测试时,它应该继续工作。

我的load_fixture功能类似于:

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

如果由于任何原因连接关闭,我还想自动重新打开连接。

1 个答案:

答案 0 :(得分:0)

您需要使用

@pytest.fixture(scope="module")

将范围保持为模块将保留整个测试套件。

和夹具中的终结器方法

`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

请原谅代码的格式化。您可以看到此link了解更多详情

你会把这个夹具称为

def test_function(run_remote_fixture_script) output = run_remote_fixture_script

希望这会有所帮助。 Finalizer方法将被称为测试套件的结束,如果范围是方法,它将在方法

之后调用