The celery_worker
fixture doesn't work when testing a flask app because the pytest fixtures that comes with celery doesn't run within flask app context.
# tasks.py
@current_app.task(bind=True)
def some_task(name, sha):
return Release.query.filter_by(name=name, sha=sha).all()
# test_celery.py
def test_some_celery_task(celery_worker):
async_result = some_task.delay(default_appname, default_sha)
assert len(async_result.get()) == 0
The tests above will simply throw RuntimeError: No application found.
And
refuse to run.
Normally when using celery inside a flask project, we have to inherit celery.Celery
and patch the __call__
method so that the actual celery tasks will run inside the flask app context, something like this:
def make_celery(app):
celery = Celery(app.import_name)
celery.config_from_object('citadel.config')
class EruGRPCTask(Task):
abstract = True
def __call__(self, *args, **kwargs):
with app.app_context():
return super(EruGRPCTask, self).__call__(*args, **kwargs)
celery.Task = EruGRPCTask
celery.autodiscover_tasks(['citadel'])
return celery
But looking at celery.contrib.pytest, I see no easy way to do the same with these fixtures, that is, to modify the base celery app so that tasks can run inside the flask app context.