如何在 PyTest 中与我的测试一起运行烧瓶?

时间:2021-07-09 10:43:09

标签: python flask pytest

通常的标志:我是 Python 新手,我是 PyTest 新手,我是 Flask 新手。

我需要创建一些独立于服务器的测试来测试调用第三方的 api。 我无法直接访问该 api,但我可以告诉它每个第三方使用什么 url。

所以我想要做的是在我运行测试时在侧面(本地主机)运行一个假的 api,所以当我正在测试的 api 需要消耗第三方时,它使用我的取而代之的是 fake-api。

所以我创建了以下 app.py

from flask import Flask
from src.fakeapi.routes import configure_routes

app = Flask(__name__)

configure_routes(app)

def start_fake_api():
    app.run(debug=True)

my_test.py

from src.fakeapi.app import start_fake_api

@start_fake_api()
def test_slack_call():

send_request_to_api_to_configure_which_url_to_use_to_call_third_party("http://127.0.0.1:5000/")

send_request_to_api_to_populate_table_using_third_party()

现在,这可能是一个过于简单的例子,但这就是想法。我的问题显然是,一旦我运行 Flask,该过程就会处于待机状态,不会继续进行测试。

我想避免在运行测试之前必须手动运行服务器,并且我想避免并行运行我的测试。

这样做的最佳方法是什么? 我可以在执行 pytest 时以某种方式执行 app.py 吗?也许通过以某种方式改变 pytest.ini ? 我可以为服务器强制运行一个新线程吗?

提前致谢!

1 个答案:

答案 0 :(得分:1)

我认为运行假服务器不是很好的理由,因为您可以使用模拟库(例如 requests-mockresponses 来响应)。

也就是说,如果您确实需要运行真正的服务器,您可以设置一个会话范围为 fixture 并进行清理。

添加 autouse 将使测试自动启动服务器,但您可以将其省略,只在测试中调用夹具,á la test_foo(fake_api)

实现 TODOed 位可能有点棘手;您可能需要以一种可以发出停止信号的方式设置 Werkzeug 服务器;例如把它wait放在threading.Event上,你就可以加注。

@pytest.mark.fixture(scope="session", autouse=True)
def fake_api():
    app = ...
    port = random.randint(1025, 65535)  # here's hoping no one is on that port
    t = threading.Thread(target=lambda: app.run(debug=True, port=port))
    t.start()
    yield port
    # TODO: implement cleanly terminating the thread here :)
相关问题