Project: pytest-tornasync

py.test plugin for testing Python 3.5+ Tornado code

Project Details

Latest version
0.6.0.post2
Home Page
https://github.com/eukaryote/pytest-tornasync
PyPI Page
https://pypi.org/project/pytest-tornasync/

Project Popularity

PageRank
0.0024553530133637623
Number of downloads
53347

================ pytest-tornasync

.. image:: https://travis-ci.org/eukaryote/pytest-tornasync.svg?branch=master :target: https://travis-ci.org/eukaryote/pytest-tornasync

A simple pytest plugin that provides some helpful fixtures for testing Tornado (version 5.0 or newer) apps and easy handling of plain (undecoratored) native coroutine tests (Python 3.5+).

Why another Tornado pytest plugin when the excellent pytest-tornado already exists? The main reason is that I didn't want to have to decorate every test coroutine with @pytest.mark.gen_test. This plugin doesn't have anything like gen_test. Defining a test with async def and a name that begins with test_ is all that is required.

Installation

Install using pip, which must be run with Python 3.5+:

.. code-block:: sh

pip install pytest-tornasync

Usage

Define an app fixture:

.. code-block:: python

import pytest


@pytest.fixture
def app():
    import yourapp
    return yourapp.make_app()  # a tornado.web.Application

Create tests as native coroutines using Python 3.5+ async def:

.. code-block:: python

async def test_app(http_server_client):
    resp = await http_server_client.fetch('/')
    assert resp.code == 200
    # ...

Fixtures

When the plugin is installed, then pytest --fixtures will show the fixtures that are available:

http_server_port Port used by http_server. http_server Start a tornado HTTP server that listens on all available interfaces.

You must create an `app` fixture, which returns
the `tornado.web.Application` to be tested.

Raises:
FixtureLookupError: tornado application fixture not found

http_server_client Create an asynchronous HTTP client that can fetch from http_server. http_client Create an asynchronous HTTP client that can fetch from anywhere. io_loop Create a new tornado.ioloop.IOLoop for each test case.

Examples

.. code-block:: python

import time

import tornado.web
import tornado.gen

import pytest


class MainHandler(tornado.web.RequestHandler):
    def get(self):
        self.write("Hello, world!")


@pytest.fixture
def app():
    return tornado.web.Application([(r"/", MainHandler)])


async def test_http_server_client(http_server_client):
    # http_server_client fetches from the `app` fixture and takes path
    resp = await http_server_client.fetch('/')
    assert resp.code == 200
    assert resp.body == b"Hello, world!"


async def test_http_client(http_client):
    # http_client fetches from anywhere and takes full URL
    resp = await http_client.fetch('http://httpbin.org/status/204')
    assert resp.code == 204


async def example_coroutine(period):
    await tornado.gen.sleep(period)


async def test_example():
    # no fixtures needed
    period = 1.0
    start = time.time()
    await example_coroutine(period)
    elapsed = time.time() - start
    assert elapsed >= period

Changes

0.6.0 (2018-11-19)

  • minor updates to avoid a pytest warning under pytest 4
  • repo switch to using a 'src' dir

0.5.0 (2018-05-28)

  • updated to work with Tornado 5, which is now the minimum required version
  • require pytest >= 3.0
  • the io_loop fixture always refers to a tornado.ioloop.IOLoop instance now
  • the io_loop_asyncio and io_loop_tornado fixtures have been removed, since now that Tornado 5 always uses asyncio under Python 3, there would be no difference between the two fixtures, so io_loop is all that is needed
  • tox tests now test more versions of Tornado (5.0.* and latest 5.), Pytest (3.0. and latest 3.*), and Python (3.5, 3.6, 3.7, and pypy3).