pytest-flask-socketio 0.1.0a0
'A pytest plugin to test Flask-SocketIO servers.'
License: MIT
Requires Python: >=3

#####################
pytest-flask-socketio
#####################

A simple `pytest <https://docs.pytest.org/en/latest/>`_ plugin for
`Flask-Socketio <https://flask-socketio.readthedocs.io/en/latest/>`_ servers.



.. image:: https://gitlab.com/tkutcher/pytest-flask-socketio/badges/dev/pipeline.svg
    :target: https://gitlab.com/tkutcher/pytest-flask-socketio/-/commits/dev
    :alt: pipeline status

.. image:: https://gitlab.com/tkutcher/pytest-flask-socketio/badges/dev/coverage.svg
    :target: https://gitlab.com/tkutcher/pytest-flask-socketio/-/commits/dev
    :alt: coverage report


.. inclusion-marker-do-not-remove


Quick Start
============

Installation
------------

You can install using pip

``$ pip install python-flask-socketio``


Usage
------------

In order to use this plugin, you must supply two fixtures (in your conftest.py)
file: ``app`` and ``socketio``.


.. code-block:: python

   # conftest.py
   import pytest
   from my_app import create_app
   from my_app import get_socketio

   @pytest.fixture
   def app():
      return create_app()  # return a Flask object for your app

   @pytest.fixture
   def socketio():
      return get_socketio()  # return the SocketIO object for your app.


.. note::
   If your application is imported here as either ``app`` or ``socketio`` you
   will need to alias it to avoid the clash between the fixture function and
   your application object.


Now, you'll have some handy fixtures available to easily have some test clients
for your app:

.. code-block:: python

   def test_single_client_connects(client):
       assert client.is_connected()

   def test_many_clients_connect(clients):
       for client in clients:
           assert client.is_connected()

   def test_some_broadcast_message(clients):
       clients[0].emit('my_custom_blast', {'blah': 'foo'})
       r1 = clients[1].get_received()
       r2 = clients[2].get_received()
       # assert things about r1 and r2

which you can then run with your normal pytest invocation:

.. code-block::

   $ pytest


This is particularly useful if your application has a concept of multiple clients in
a single room and you need to mock several clients interactions. You could customize
some of the parameters the fixtures use to your preference.

For example, say you have a game server that always emits a particular message named
``"move"`` with data in the form ``{"x": 0, "y": 1}``. You could write a custom
class to assert things about that move


.. code-block:: python

    from pytest_flask_socketio import EventReceiver  # just wraps a list

    class MyAppsEventReceiver(EventReceiver):
        def got_move(x, y, message_index=0) -> bool:
            return self.data[message_index]['name'] == 'move' and \
                self.data[message_index][0]['x'] == x and \
                self.data[message_index][0]['y'] == y


Then use it in your tests:

.. code-block:: python

    client_idents = ['player-A', 'player-B']
    event_receiver = MyAppsEventReceiver


    def test_player_move(clients):
        """ Tests Player B gets Player A's move. """
        clients['player-A'].emit('make_move', {'x': 1, 'y': 8})
        assert clients['player-B'].get_received().got_move('1', '8')



Check out the docs for more information on how you can use this plugin.


More documentation to come.




Developing
==========

- Contributions welcome!
- This is a simple package but I feel it could be extended to make some handy utilities (to be honest mainly just wanted an
  actual-maybe-somewhat-useful-package on pypi)