pytest-tornado is a plugin for the Pytest testing framework that simplifies testing asynchronous Tornado applications. It provides a set of fixtures and markers designed to integrate Tornado's asynchronous features seamlessly into pytest tests. The current version is 0.8.1, released on June 17, 2020, and the project has an infrequent release cadence.
pip install pytest-tornadoVerified import paths — ran on the pinned version, not inferred.
This quickstart demonstrates how to test a simple Tornado web application using `pytest-tornado`. It defines a Tornado application, provides it via a `pytest` fixture named `app`, and then uses the `@pytest.mark.gen_test` marker along with `http_client` and `base_url` fixtures to perform an asynchronous HTTP request and assert the response.
For native `async def` tests, consider `pytest-tornasync` or ensure `@pytest.mark.gen_test` is correctly applied. For complex scenarios, you might need to combine it with `pytest-asyncio` (see next warning).
If using both, ensure the `@pytest.mark.asyncio` decorator, if needed to manage the event loop, wraps `@pytest.mark.gen_test` for the `asyncio` loop to be properly initiated. Alternatively, streamline your setup to primarily use one async plugin if possible, or ensure explicit `IOLoop` management if mixing concerns.
Ensure any manually created `IOLoop` instances are properly stopped (e.g., `io_loop.stop()`, `io_loop.close()`) in test teardown or fixture finalizers. If the `IOLoop` is in another thread, ensure you stop the *correct* `IOLoop` instance from that thread.
Ensure that any custom `tornado.ioloop.IOLoop` instances are explicitly stopped using `io_loop.stop()` and `io_loop.close()`. If the IOLoop is in a separate thread, make sure you are stopping the instance created and running within that specific thread. pytest-tornado's provided fixtures (e.g., `http_server`) should handle their IOLoop lifecycle automatically.
If using `pytest-asyncio`, ensure its decorator (`@pytest.mark.asyncio`) is placed *outside* or manages the context for `@pytest.mark.gen_test` if both are applied. For simple native coroutine tests with Tornado 5.0+, consider if `pytest-tornasync` is a better fit as it handles `async def` more directly.
Run the Tornado application in a separate thread or process that is distinct from the main test `IOLoop` where the blocking browser automation operates. This allows the server to respond independently of the blocking client.