在 Popen 上等待标准输出

Wait for stdout on Popen

我正在尝试为 Flask 应用程序设置验收测试工具,目前我正在努力等待应用程序启动后再进行调用。

以下构造工作正常:

class SpinUpTests(unittest.TestCase):
def tearDown(self):
    super().tearDown()
    self.stubby_server.kill()
    self.stubby_server.communicate()

def test_given_not_yet_running_when_created_without_config_then_started_on_default_port(self):
    self.not_yet_running(5000)

    self.stubby_server = subprocess.Popen(['python', '../../app/StubbyServer.py'], stdout=subprocess.PIPE)
    time.sleep(1)#<--- I would like to get rid of this

    self.then_started_on_port(5000)

我想在标准输出上等待:

self.stubby_server = subprocess.Popen(['python', '../../app/StubbyServer.py'], stdout=subprocess.PIPE) time.sleep(1)#<--- 我想去掉这个

我试过了

for line in self.stubby_server.stdout.readline()

但是 readline() 永远不会完成,我已经在测试输出 window.

中看到了输出

有什么想法可以等待 flask 应用程序启动而无需使用显式 sleep()

使用 retry 包,这将有助于解决您的问题。最终,你设置 what 你想重试, what 异常你想重试,你可以根据如何设置具体的计时参数你想重试。它有很好的记录。

这是我如何在我从事的项目之一中解决此问题的示例 here

如果 link 不起作用,下面是对您有帮助的代码片段:

@classmethod
def _start_app_locally(cls):
    subprocess.Popen(["fake-ubersmith"])
    retry_call(
        requests.get,
        fargs=["{}/status".format(cls.endpoint)],
        exceptions=RequestException,
        delay=1
    )

如您所见,我只是尝试使用 requests 使用 get 到达我的端点(fargs 是传递给 requests.get 的参数,如您所见它调用 back 您传递给 retry_call) 的方法,并且根据我预期的 RequestException,我会延迟 1 秒重试。

最后,"fake-ubersmith" 是将 运行 您的服务器的命令,这最终是您的类似命令:'python', '../../app/StubbyServer.py'