Skip to main content

No project description provided

Project description

pytest-sanic
============

.. image:: https://travis-ci.org/yunstanford/pytest-sanic.svg?branch=master
:alt: build status
:target: https://travis-ci.org/yunstanford/pytest-sanic

.. image:: https://coveralls.io/repos/github/yunstanford/pytest-sanic/badge.svg?branch=master
:alt: coverage status
:target: https://coveralls.io/github/yunstanford/pytest-sanic?branch=master


A pytest plugin for `Sanic <http://sanic.readthedocs.io/en/latest/>`. It helps you to test your code asynchronously.

This plugin provides:

* very easy testing with async coroutines
* common and useful fixtures
* test_client for Sanic application
* test_server for Sanic application


-------
Install
-------

.. code::

pip install pytest-sanic


-----------
Quick Start
-----------

You don't have to load `pytest-sanic` explicitly. pytest will do it for you. Just write tests like,

.. code::

async def test_sanic_db_find_by_id(app):
"""
Let's assume that, in db we have,
{
"id": "123",
"name": "Kobe Bryant",
"team": "Lakers",
}
"""
doc = await app.db["players"].find_by_id("123")
assert doc.name == "Kobe Bryant"
assert doc.team == "Lakers"


--------
Fixtures
--------

Some fixtures for easy testing.

``loop``
~~~~~~~~

`pytest-sanic` creates an event loop and injects it as a fixture. `pytest` will use this event loop to run your `async tests`.
By default, fixture `loop` is an instance of `asyncio.new_event_loop`. But `uvloop` is also an option for you, by simpy passing
`--loop uvloop`. Keep mind to just use one single event loop.


``unused_port``
~~~~~~~~~~~~~~

an unused TCP port on the localhost.


``test_server``
~~~~~~~~~~~~~~

Creates a TestServer instance by giving a `Sanic` application. It's very easy to utilize `test_server` to create your `Sanic`
application server for testing.

.. code::

@pytest.yield_fixture
def app():
app = Sanic("test_sanic_app")

@app.route("/test_get", methods=['GET'])
async def test_get(request):
return response.json({"GET": True})

yield app

@pytest.fixture
def sanic_server(loop, app, test_server):
return loop.run_until_complete(test_server(app))


``test_client``
~~~~~~~~~~~~~~

Creates a TestClient instance by giving a `Sanic` application. You can simply have a client by using `test_client`, like

.. code::

@pytest.yield_fixture
def app():
app = Sanic("test_sanic_app")

@app.route("/test_get", methods=['GET'])
async def test_get(request):
return response.json({"GET": True})

@app.route("/test_post", methods=['POST'])
async def test_post(request):
return response.json({"POST": True})

@app.route("/test_put", methods=['PUT'])
async def test_put(request):
return response.json({"PUT": True})

@app.route("/test_delete", methods=['DELETE'])
async def test_delete(request):
return response.json({"DELETE": True})

@app.route("/test_patch", methods=['PATCH'])
async def test_patch(request):
return response.json({"PATCH": True})

@app.route("/test_options", methods=['OPTIONS'])
async def test_options(request):
return response.json({"OPTIONS": True})

@app.route("/test_head", methods=['HEAD'])
async def test_head(request):
return response.json({"HEAD": True})

@app.websocket("/test_ws")
async def test_ws(request, ws):
data = await ws.recv()
await ws.send(data)

yield app

@pytest.fixture
def test_cli(loop, app, test_client):
return loop.run_until_complete(test_client(app, protocol=WebSocketProtocol))

#########
# Tests #
#########

async def test_fixture_test_client_get(test_cli):
"""
GET request
"""
resp = await test_cli.get('/test_get')
assert resp.status == 200
resp_json = await resp.json()
assert resp_json == {"GET": True}

async def test_fixture_test_client_post(test_cli):
"""
POST request
"""
resp = await test_cli.post('/test_post')
assert resp.status == 200
resp_json = await resp.json()
assert resp_json == {"POST": True}

async def test_fixture_test_client_put(test_cli):
"""
PUT request
"""
resp = await test_cli.put('/test_put')
assert resp.status == 200
resp_json = await resp.json()
assert resp_json == {"PUT": True}

async def test_fixture_test_client_delete(test_cli):
"""
DELETE request
"""
resp = await test_cli.delete('/test_delete')
assert resp.status == 200
resp_json = await resp.json()
assert resp_json == {"DELETE": True}

async def test_fixture_test_client_patch(test_cli):
"""
PATCH request
"""
resp = await test_cli.patch('/test_patch')
assert resp.status == 200
resp_json = await resp.json()
assert resp_json == {"PATCH": True}

async def test_fixture_test_client_options(test_cli):
"""
OPTIONS request
"""
resp = await test_cli.options('/test_options')
assert resp.status == 200
resp_json = await resp.json()
assert resp_json == {"OPTIONS": True}

async def test_fixture_test_client_head(test_cli):
"""
HEAD request
"""
resp = await test_cli.head('/test_head')
assert resp.status == 200
resp_json = await resp.json()
# HEAD should not have body
assert resp_json is None

async def test_fixture_test_client_ws(test_cli):
"""
Websockets
"""
ws_conn = await test_cli.ws_connect('/test_ws')
data = 'hello world!'
await ws_conn.send_str(data)
msg = await ws_conn.receive()
assert msg.data == data
await ws_conn.close()

A small note: `test_cli.ws_connect` does not work in `sanic.__version__ <= '0.5.4'`, because of a Sanic bug, but it
has been fixed in master branch.


-----------
Development
-----------

`pytest-sanic` accepts contributions on GitHub, in the form of issues or pull requests.


Run unit tests.

.. code::

./uranium test


---------
Reference
---------

Some useful pytest plugins:

* `pytest-tornado <https://github.com/eugeniy/pytest-tornado>`
* `pytest-asyncio <https://github.com/pytest-dev/pytest-asyncio>`
* `pytest-aiohttp <https://github.com/aio-libs/pytest-aiohttp>`

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

pytest-sanic-0.1.1.tar.gz (7.5 kB view details)

Uploaded Source

Built Distribution

pytest_sanic-0.1.1-py2.py3-none-any.whl (12.3 kB view details)

Uploaded Python 2 Python 3

File details

Details for the file pytest-sanic-0.1.1.tar.gz.

File metadata

File hashes

Hashes for pytest-sanic-0.1.1.tar.gz
Algorithm Hash digest
SHA256 05419c3cbd46ae6ea12ddc120552809ae2ff321ff0a3ffd4a9365a2390f01c3d
MD5 f17339f5dfd5a2e2fde0842653a54d92
BLAKE2b-256 ca2553909ad56bf2ee842589fce653e47e4a1879aa2ab3e47d1f5de83c99dd1f

See more details on using hashes here.

Provenance

File details

Details for the file pytest_sanic-0.1.1-py2.py3-none-any.whl.

File metadata

File hashes

Hashes for pytest_sanic-0.1.1-py2.py3-none-any.whl
Algorithm Hash digest
SHA256 3fcecb05c58a86767096be9a9d23a94902e30647d7fdb694b62e2016ed30a157
MD5 cf9bbd3290d4771d232cbb7e7f689f2d
BLAKE2b-256 9116c3ae421d38d31033504ba68404a286f389f590acab164ab26f5e91c79c51

See more details on using hashes here.

Provenance

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page