diff --git a/docs/sanic/extensions.md b/docs/sanic/extensions.md index da49da89..92b61f8c 100644 --- a/docs/sanic/extensions.md +++ b/docs/sanic/extensions.md @@ -23,3 +23,4 @@ A list of Sanic extensions created by the community. - [sanic-prometheus](https://github.com/dkruchinin/sanic-prometheus): Prometheus metrics for Sanic - [Sanic-RestPlus](https://github.com/ashleysommer/sanic-restplus): A port of Flask-RestPlus for Sanic. Full-featured REST API with SwaggerUI generation. - [sanic-transmute](https://github.com/yunstanford/sanic-transmute): A Sanic extension that generates APIs from python function and classes, and also generates Swagger UI/documentation automatically. +- [pytest-sanic](https://github.com/yunstanford/pytest-sanic): A pytest plugin for Sanic. It helps you to test your code asynchronously. diff --git a/docs/sanic/testing.md b/docs/sanic/testing.md index d4f61b4c..b8427a00 100644 --- a/docs/sanic/testing.md +++ b/docs/sanic/testing.md @@ -57,3 +57,71 @@ def test_post_json_request_includes_data(): More information about the available arguments to aiohttp can be found [in the documentation for ClientSession](https://aiohttp.readthedocs.io/en/stable/client_reference.html#client-session). + + +# pytest-sanic + +[pytest-sanic](https://github.com/yunstanford/pytest-sanic) is a pytest plugin, it helps you to test your code asynchronously. +Just write tests like, + +```python +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" +``` + +[pytest-sanic](https://github.com/yunstanford/pytest-sanic) also provides some useful fixtures, like loop, unused_port, +test_server, test_client. + +```python +@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}) + + 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} +```