【问题标题】:Python: How to tests a program that uses fork?Python:如何测试使用 fork 的程序?
【发布时间】:2017-07-07 15:23:10
【问题描述】:

我正在编写一个程序,它在生产中使用相同代码的多个实例。然后实例通过网络进行通信,但这在这里无关紧要。

在开发过程中,我多次 fork 初始过程以获得完整的实例设置,非常方便。

但是,尝试对此编写集成测试给我带来了问题:测试框架(unittest/nosetests/py.test)当然也是分叉的,所以我最终得到了多个副本测试框架,提供了乱码的结果作为输出每个孩子的单元测试重叠。

一个简化的例子:

  • 程序是聊天客户端,通过某种网络连接(例如,redis pubsub)连接到另一个客户端
  • 程序公开了一个 API 来发布和阅读消息
  • 我想分叉两个相互连接的程序实例
  • 测试应使用 API 来确保客户端通过相互发送/接收消息来工作
  • 主进程监督子进程的错误并运行测试套件

为此,我需要从子进程中“卸载”或停止测试框架。我该怎么做?

我可以通过仅在分叉子项后调用测试套件来解决此问题,但我需要为每次测试重新启动所有子项。

【问题讨论】:

  • 您能否扩展一下乱码结果,并大致了解您尝试测试的代码和期望的结果。
  • 完成 - 希望这更容易理解。
  • 我认为你的问题在于输出,因为 stdout 不是线程安全的。您可以尝试为每个进程重定向标准输出,或者重构您的代码以注入输出车辆。
  • 我不这么认为。 Fork 复制了整个过程。所以分叉两次,我最终得到了同一个进程的三个实例,都在运行 unittest。所以所有的测试基本上都执行了 3 次,也产生了 3 次输出。

标签: python testing pytest python-unittest nose


【解决方案1】:

在这种情况下分叉一个进程很麻烦,因为子进程继承父进程的完整堆栈,包括正在运行的测试框架实例。

基本上有两种方法可以解决这个问题:

第一是在初始化测试框架之前分叉,然后从测试中访问子进程。如果子进程的生命周期很长,这很有效,但如果要在每个测试中启动子进程,甚至可能使用不同的测试夹具/场景,这会很麻烦。

第二个是通过使用subprocess / Popen 简单地启动进程来放弃所有的分叉。我找到了一个名为 xprocess 的 pytest 插件,它可以帮助您完成这项任务。它没有提供我真正需要的东西,但它为我指明了正确的方向。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多