Тесты Django зависают при выполнении асинхронных задач Celery

Я пытаюсь создать модульные тесты в Django, которые проверяют задачи Celery и то, создает ли задача объекты из данных CSV, которые я ей передаю.

По какой-то странной причине мои тесты зависают при вызове .get() на AsyncResult -objects.

Однако, когда я наблюдаю за журналами Celery и базой данных, кажется, что они работают нормально и возвращают сообщения об успехе, указывающие на то, что задачи выполнены.

Вне тестовой среды все работает нормально, просто когда я запускаю Celery в своих тестах. Я понятия не имею, что происходит.

Вот соответствующий код:

stations/test.py

class StationsTests(TestCase):
    
    @classmethod
    def setUpTestData(cls):
        super(StationsTests, cls).setUpTestData()
        dirname = os.path.abspath(os.path.join(os.path.dirname( __file__ ), '..', 'csvimport'))

        cls.csv_data_type_station = 'station'
        cls.upload_type = 'safe_create'
        cls.file_station = os.path.join(dirname, 'CSVFiles/Station_test_csv.csv')


    @override_settings(CELERY_EAGER_PROPAGATES_EXCEPTIONS=True,
                    CELERY_ALWAYS_EAGER=True)
    def test_station_geoJSON_data(self):
        self.result_upload_csv = upload_csv.delay(
            self.file_station, self.csv_data_type_station, self.upload_type).get(timeout=10)

        self.assertEqual(self.result_upload_csv, '10 stations uploaded successfully')
        self.assertEqual(len(Station.objects.all()), 10)

settings.py:

DATABASES = {
    'default': {
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'NAME': 'db_hcbapp',
        'USER': 'postgres',
        'PASSWORD': 'postgres',
        'HOST': 'localhost',
        'PORT': '5432'
    },
}
.....

CELERY_BROKER_URL = 'redis://127.0.0.1:6379'
CELERY_IMPORTS = ('csvimport.tasks')
CELERY_ACCEPT_CONTENT = ['application/json']
CELERY_RESULT_SERIALIZER = 'json'
CELERY_TASK_SERIALIZER = 'json'
CELERY_RESULT_BACKEND = 'django-db'
CELERY_RESULT_EXTENDED = True

celery.py:

from __future__ import absolute_import, unicode_literals
import os
from celery import Celery
from django.conf import settings

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'myapp.settings')
app = Celery('myapp')
app.conf.enable_utc = False
app.config_from_object(settings, namespace='CELERY')

app.autodiscover_tasks()

@app.task(bind=True)
def debug_task(self):
    print('Request: {0!r}'.format(self.request))

tasks.py:

Как я уже сказал, вне тестирования задача и база данных работают отлично. Redis и Celery работают, и результаты задачи добавляются в базу данных PostgreSQL.

Есть идеи, что может быть причиной зависания?

  • Я пробовал подражать тестовому методу, используя @patch('myapp.tasks.upload_csv.delay'), но это, похоже, не создает никаких объектов в моей реальной базе данных. Следовательно, с помощью self.assertEqual(len(Station.objects.all()), 10) я хочу проверить, что задача создает объекты в моей базе данных.

  • Я пробовал изменить мою базу данных обратно на SQLite, но она все равно зависает.

  • Я пробовал создавать другие простые временные задачи в tasks.py. Но даже они замирают.

Есть идеи?

Я разобрался с этим, возможно, это поможет и другим!

Очевидно, что тест выполнялся в отдельной базе данных, в то время как задача Celery использовала мою реальную базу данных. Поэтому, хотя Celery / Redis работали и возвращали значения, они не возвращали значения в мой тестовый env. В некотором смысле это немного очевидно.

Я рекомендую использовать @override_settings(CELERY_TASK_ALWAYS_EAGER=True) в методе тестирования, таким образом, он будет включен в процесс тестирования !

Вернуться на верх