【问题标题】:Run part of Python unit tests on remote Linux machine from a Windows host从 Windows 主机在远程 Linux 机器上运行部分 Python 单元测试
【发布时间】:2015-08-19 07:54:01
【问题描述】:

我的情况是这样的:

  • 我有一个基于 windows 的服务器程序和一个基于 linux 的客户端。
  • 我对在本地 linux 机器上运行和需要运行的 linux 客户端进行了许多测试
  • 我需要从 windows 服务器机器上运行一些代码,它将一些消息发送到 linux 客户端。然后,应在 linux 客户端计算机上执行测试以验证这些消息的效果

所以一个典型的测试用例看起来像这样,在 windows 主机上运行:

test_example_message(self):
    # has to be executed locally on windows server
    send_message(EXAMPLE, hosts)
    # has to be executed locally on linux clients
    for host in hosts:
        verify_message_effect(EXAMPLE, host)

我发现 pytest-xdist 能够以某种方式做到这一点。

我有什么好的教程或代码示例如何使用它?

【问题讨论】:

  • 我目前找到的一些资源:xdist & django ;;; intro to py.test
  • 另一个(捷克语):[horejsek.blog] (blog.horejsek.com/co-se-mi-libi-na-pytestu)
  • 这看起来很恶心!我个人认为你应该在你的单元测试中模拟主机之间的通信,但如果你真的想这样做,你也可以使用ssh <user_with_ssh_key>@<remotehost> python execute_verification.py 在你的 linux 机器上简单地执行你的验证脚本,然后使用check_output 捕获它的输出和验证 Windows 主机上的返回值。
  • @flazzarini 是的,我最终决定编写自己的“堆栈”,使用在多个线程/进程中执行的 ssh。 (在我的情况下,并行化至关重要)。经过一番研究,我发现无论如何我都需要用 xdist 来做这件事(即编写远程执行堆栈)。
  • 好吧,你可以在这里回答你自己的问题。

标签: python linux windows pytest xdist


【解决方案1】:

我的最终设计使用 ssh 和多处理而不是 xdist(在 execute_tc() 函数中):

import multiprocessing
import test_functions

def test_example_message(self):
"""Example test case"""
    # to get IPs, usernames, passwords, other required data
    config = get_test_config('example_message')
    # will take care of threading and executing parts
    result_dict = execute_tc(config)
    # to fail or not to fail. take care of proper reporting
    process_results(result_dict)

def execute_tc(config):
"""Execute test code in parallel"""
    # create shared results dictionary
    manager = multiprocessing.Manager()
    result_dict = manager.dict({})
    # create processes
    processes = []
    for func, platform, args in config:
        function = getattr(test_functions, func)
        worker = multiprocessing.Process(target=function, args=[result_dict, platform, args])
        worker.daemon = True
        worker.start()
        processes.append(worker)

    for process in processes:
        process.join()

    return result_dict

【讨论】:

  • 我发现这个例子在处理 ssh 时特别有用:sebastiandahlgren.se/2012/10/11/…
  • 我总是发现分布式/SSH 集成测试是很有趣的东西(并且没有很好的文档或博客)。感谢更新。
  • 我为此使用 SSH (Paramiko)。我正在测试一个大系统,太大而无法模拟,太大而无法“启动-运行-测试和销毁”。 (而不是模拟,我们有不断检查或回滚实验室到已知状态的脚本)。我使用 Paramiko (SSH) 来“在服务器 A 上做事,等待,然后检查服务器 B 上的状态(它消耗来自 A 的下游数据)。如果我从头开始,我可能会倾向于 Spur.py 而不是 Paramiko。
【解决方案2】:
def execute_tc(config):
"""Execute test code in parallel"""
    # create shared results dictionary
    manager = multiprocessing.Manager()
    result_dict = manager.dict({})
    # create processes
    processes = []
    for func, platform, args in config:
        function = getattr(test_functions, func)
        worker = multiprocessing.Process(target=function, args=[result_dict, platform, args])
        worker.daemon = True
        worker.start()
        processes.append(worker)

    for process in processes:
        process.join()

    return result_dict

我认为您已经更改了执行测试用例的方法来执行特定的测试用例。

【讨论】:

  • “函数”负责具体执行什么,具体取决于“平台”参数。 def test_function(result_dict, platform,[server,...]): if platform == 'windows': result_dict['windows'] = do_sth_locally() else: result_dict[platform] = ssh_execute('remote_func', server)
猜你喜欢
  • 1970-01-01
  • 2015-01-19
  • 1970-01-01
  • 1970-01-01
  • 2015-07-30
  • 1970-01-01
  • 2022-10-06
  • 2015-09-16
  • 1970-01-01
相关资源
最近更新 更多