Pytest Celery Plugin
pytest-celery is a pytest plugin that provides fixtures and utilities for testing Celery applications. It streamlines setting up and tearing down Celery workers and brokers (like Redis, RabbitMQ, SQS) within your pytest test suite. Currently at version 1.3.0, it maintains an active development pace with frequent updates to support new Python and Celery versions, and address compatibility issues.
Warnings
- breaking Python 3.8 support was dropped in `pytest-celery` v1.3.0. Users on Python 3.8 must upgrade their Python environment or pin `pytest-celery` to a version prior to 1.3.0.
- gotcha The `pycurl` dependency for SQS transport was removed in v1.2.0 (in favor of `urllib3`) and then re-added in v1.3.0 to match `celery`/`kombu` v5.6 SQS transport requirements. This flip-flop can cause unexpected dependency issues for users relying on SQS brokers, depending on their `pytest-celery` and `celery`/`kombu` versions.
- gotcha By default, `celery_app` and `celery_worker` fixtures have a `function` scope, meaning they are created and torn down for each test. For performance, especially with many tests, consider using the `session` scoped fixtures (`celery_session_app`, `celery_session_worker`) or customizing the scope of the default fixtures.
- gotcha From v1.3.0, `setuptools` was removed from dependencies. While not directly breaking for users, projects with custom build systems or highly specific environments that previously relied on `pytest-celery` implicitly bringing `setuptools` might need adjustments.
Install
-
pip install "pytest-celery[all]" -
pip install pytest-celery
Imports
- pytest_celery fixtures
import pytest; # Fixtures like celery_app, celery_worker are auto-discovered
Quickstart
import pytest
from celery import Celery
@pytest.fixture(scope="session")
def celery_config():
return {
"broker_url": "redis://localhost:6379/0",
"result_backend": "redis://localhost:6379/0",
"task_always_eager": False,
"task_eager_propagates": False
}
@pytest.fixture(scope="session")
def celery_enable_logging():
return True
@pytest.fixture(scope="session")
def celery_worker_parameters():
return {
'queue': ['celery'],
'pool': 'solo'
}
# Assuming you have a tasks.py module with a simple task
# e.g., tasks.py:
# from celery import shared_task
# @shared_task
# def add(x, y):
# return x + y
def test_add_task(celery_app: Celery, celery_worker):
# Ensure tasks.py is discoverable, e.g., by adding a custom Celery app fixture
# or importing tasks directly if they are in the test file.
from my_app.tasks import add # Replace with your actual task module
result = add.delay(2, 3)
assert result.get(timeout=10) == 5
assert result.successful()