通常的标志:我是 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 ? 我可以为服务器强制运行一个新线程吗?
提前致谢!
答案 0 :(得分:1)
我认为运行假服务器不是很好的理由,因为您可以使用模拟库(例如 requests-mock
或 responses
来响应)。
也就是说,如果您确实需要运行真正的服务器,您可以设置一个会话范围为 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 :)