Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Keyerror when testing socketio connection with get_received() #295

Closed
artiom33 opened this issue Aug 2, 2016 · 6 comments
Closed

Keyerror when testing socketio connection with get_received() #295

artiom33 opened this issue Aug 2, 2016 · 6 comments
Assignees
Labels

Comments

@artiom33
Copy link

artiom33 commented Aug 2, 2016

Hi everyone,

Recently I decided to upgrade flask-socketio in my app and encountered an error that I thought was originally related to some old dependencies. However, after I managed to replicate it using an example app I started thinking that it might be a package error.

I use ubuntu 14.04 and here are the packages I have in my venv:

click==6.6
eventlet==0.19.0
Flask==0.11.1
Flask-SocketIO==2.6
greenlet==0.4.10
itsdangerous==0.24
Jinja2==2.8
MarkupSafe==0.23
python-engineio==0.9.2
python-socketio==1.4.3
six==1.10.0
Werkzeug==0.11.10

Here is app.py:

from flask import Flask, render_template
from flask_socketio import SocketIO, emit

socketio = SocketIO()

def create_app():
    app = Flask(__name__)
    app.config['SECRET_KEY'] = 'secret!'
    socketio.init_app(app)` 
   @app.route('/')
    def index():
        socketio.emit('my response', {'data': 'got it!'})
        return "Hello world"

    return app

if __name__ == '__main__':
    app = create_app()
    socketio.run(app)

Here is my test case in test/test_socketio.py

import unittest

import flask
from flask.ext.socketio import SocketIO

from app import create_app, socketio

class SocketsTestCase(unittest.TestCase):
    def setUp(self):
        self.app = create_app()

    def test_connect(self):
        self.socket_client = socketio.test_client(self.app)
        received = self.socket_client.get_received()
        self.assertEqual(len(received), 0)

I use unittest discover to run tests, but I think you might also need __init__.py in test folder.

@miguelgrinberg
Copy link
Owner

What client are you using? How is it initialized?

Typically the /index route in the Flask app serves the client application to the browser. That seems to be missing here. You also don't seem to have any socket.io handlers, the functions that you decorate with @socketio.on

@artiom33
Copy link
Author

artiom33 commented Aug 2, 2016

Hi Miguel,

by saying client you mean browser or javascript library? The main goal I am trying to archive with this reproducible example is to pass the unit test.

@miguelgrinberg
Copy link
Owner

miguelgrinberg commented Aug 2, 2016

Nobody connects to the index route you created in your test. So the test will never pass in this form. You can connect to / in your test, and maybe that will make it pass. But I see no point in writing code just for a test to pass. A real world application will need to have more stuff in it to be useful.

@artiom33
Copy link
Author

artiom33 commented Aug 2, 2016

Hi, thanks for your help and your speedy response.

I don't understand why this test should not pass. As you correctly point out the test client in the unit test does not connect to any route. However, we are trying to assert that no socketIO messages are received by the test client. The failure in this test is an error in calling the function self.socket_client.get_received(), as follows:

======================================================================
ERROR: test_with_connection (test.testing_socketio.SocketsTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/artiom/socketioex/test/testing_socketio.py", line 21, in test_with_connection
    received = self.socket_client.get_received()
  File "/home/artiom/socketioex/venv/local/lib/python2.7/site-packages/flask_socketio/test_client.py", line 143, in get_received
    r = [pkt for pkt in self.queue[self.sid]
KeyError: 'bc554a1249a94745ba7e981d08621a8b'

Is it the case that it is not possible to call the function SocketIOTestClient.get_received, unless you already received a socketIO message? If so, then our mistake is to have tests of this form, since we are trying to check that in certain cases no socketio message will be sent. (This is a minimal example - our actual test cases involve several endpoints being accessed, however because of certain conditions, no socketio messages are sent).

If this is not the case, can you explain why you don't think this test should pass?

@miguelgrinberg
Copy link
Owner

Sorry. I was sort of thrown off by the way you coded your application, putting an emit in the index route. I did not actually fully read your test and did not realize you were actually testing for no messages. I somehow assumed you expected to see that emit in the test results.

A fix for the KeyError is coming up in a couple of minutes.

@miguelgrinberg miguelgrinberg self-assigned this Aug 2, 2016
@artiom33
Copy link
Author

artiom33 commented Aug 2, 2016

Thanks a lot, looking forward to the fix.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants