Skip to content

SM_BG_TASKS_TASK_ALWAYS_EAGER ineffective for tests that don't use the client fixture #71

Description

@antosubash

Summary

SM_BG_TASKS_TASK_ALWAYS_EAGER=true is documented as the way to run Celery tasks inline in tests. In practice, the eager-mode patch only takes effect after host_conftest._patch_celery_eager() runs AND after the FastAPI lifespan fires (the client fixture). Tests that only use the db fixture (no client) never trigger the lifespan, never resolve the global Celery app, and task.delay() tries to hit the real broker.

Reproduction

@pytest.fixture
async def db(): ...  # NullPool postgres, no app boot

@pytest.mark.asyncio
async def test_generation_job(db, seed_dataset):
    sample = await create_sample(...)
    await db.commit()
    from lacowiki_sampling.tasks import generate_sample
    result = generate_sample.delay(sample_id=sample.id).get(timeout=10)
    # ↑ kombu.exceptions.OperationalError: connection refused (broker)

If you add the client fixture, lifespan fires, eager mode kicks in, and the test passes.

Workaround currently used

Every module's tests/conftest.py needs:

def _ensure_celery_eager() -> None:
    from background_tasks import celery_app as _ca
    from background_tasks.settings import BackgroundTasksSettings
    settings = BackgroundTasksSettings()
    celery = _ca.build_celery(settings)
    celery.conf.task_always_eager = True
    celery.conf.task_eager_propagates = True

_ensure_celery_eager()

This eagerly bootstraps the Celery app at conftest import time (before any test fixtures resolve), so task.delay() finds it and respects the eager flag.

Suggested fix

The patch in host_conftest._patch_celery_eager should also call build_celery() once at module load to register the global Celery app. That way module conftests don't need to repeat the bootstrap.

Alternatively, change simple_module_background_tasks so BackgroundTasksSettings.task_always_eager is honoured by build_celery directly (read at instantiation), and the framework calls build_celery() from host_conftest regardless of lifespan firing.

Impact

Every module testing a Celery task without using the FastAPI test client carries this conftest hack.

Environment

  • simple_module_background_tasks==0.0.3, celery>=5.3
  • Discovered Phase 4 (sampling generation_job tests).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions