Flask: How to Test WebSocket with Flask-SocketIO
#python , #flask , #Flask-SocketIO , #SocketIO , #pytest , #english-version
I had a project built with Flask (Python) and wanted to add some tests.
In the project, there’s a WebSocket using Flask-SocketIO — but how do we test that?
I did some digging and here’s what I found.
Talk is cheap. Show me the code
Start by creating a simple Flask + SocketIO app main.py:
from flask import Flask, render_templatefrom flask_socketio import SocketIO, send
socketio = SocketIO()
app = Flask(__name__)app.config["SECRET_KEY"] = "secret!"
@socketio.on("message")def handle_message(data): print("server socketio received message: " + data) send(f"server got: {data}")
@socketio.on_error()def error_handler(e): print("socketio error:", e)
@app.route("/")def hello_world(): return "Hello, World!"
def create_app(): socketio.init_app(app) return app
if __name__ == "__main__": app = create_app() socketio.run(app)Then create a pytest test file test_main.py:
import pytestfrom main import create_app, socketiofrom flask.testing import FlaskClientfrom flask_socketio.test_client import SocketIOTestClient
@pytest.fixture()def app(): app = create_app() app.config.update({"TESTING": True}) yield app
@pytest.fixture()def flask_client(app): return app.test_client()
@pytest.fixture()def runner(app): return app.test_cli_runner()Next, create a SocketIO test client with socketio.test_client(app)
The socketio.test_client(app) must use the app created from the pytest fixture above:
@pytest.fixture()def socketio_client(app): socketio_client = socketio.test_client(app) return socketio_client⚠️ Gotcha!
The socketio in socketio.test_client(app) is the same socketio = SocketIO() from main.py.
Write a test case for SocketIO:
def test_socketio_message(socketio_client: SocketIOTestClient): socketio_client.send("hello from pytest") recv = socketio_client.get_received() print("test_socketio_message recv", recv)
assert len(recv) == 1 assert recv[0]["name"] == "message" assert recv[0]["args"] == "server got: hello from pytest" assert recv[0]["namespace"] == "/"Then run the test with:
pytestDone! We can finally test WebSocket! 🎉