1
0
forked from erp-dev/erp
Files
erpnew/docs/celery_testing.md

4.2 KiB
Raw Blame History

Celery 任务测试指南

1. 自动化测试(单元测试/CI

项目新增了三个演示型任务(api_v1/tasks.py

任务 功能
ping_task(message='ping') 打印并返回时间戳,用于快速验证 worker 是否可接收/返回结果
merchant_product_count(merchant_id) 统计某商户下产品数量,示范如何在任务中访问数据库
backup_database(output_dir=None, filename_prefix='db-backup') 将当前数据库导出为 .sql 文件(数据备份),默认保存到 BASE_DIR/data-bak/

对应的单元测试位于 api_v1/tests.py(类 CeleryTasksTestCase),通过 @override_settings(CELERY_TASK_ALWAYS_EAGER=True) 让任务在测试进程内同步执行。

运行方式:

uv run manage.py test api_v1.tests.CeleryTasksTestCase

若要在其他测试中调用任务,只需在测试类上使用同样的 override_settings 即可保证 Celery 在没有 worker 的情况下仍能同步执行。


2. 本地验证真实 workerRabbitMQ + Celery

2.1 启动依赖服务

# 启动基础设施Postgres/Redis/Rabbit/Celery worker/web
docker compose up -d postgres redis rabbitmq

# 启动 webDjango
docker compose up -d web

# 启动 Celery worker如已运行可跳过
docker compose up -d celery_worker
# 或者手动uv run celery -A flower worker -l info

若 worker 容器异常,可通过 docker compose restart celery_worker 重启。

2.2 发送测试任务

在另一个终端进入容器或宿主项目目录执行:

uv run python manage.py shell
from api_v1.tasks import ping_task, merchant_product_count, backup_database
from basic_info.models import Merchant

# 发送心跳任务
async_result = ping_task.delay('hello celery')
print(async_result.get(timeout=10))

# 发送统计任务(示例:使用 ID=1 的商户)
merchant = Merchant.objects.first()
result = merchant_product_count.delay(merchant.id)
print(result.get(timeout=10))

# 触发数据库备份(输出到默认 data-bak
backup = backup_database.delay(filename_prefix='manual-backup')
print(backup.get(timeout=30))  # payload 中包含 backup_path文件为 .sql

2.3 观察执行结果

  1. Worker 日志docker compose logs -f celery_worker
    可查看任务被消费、日志输出等信息。
  2. RabbitMQ 控制台:访问 http://localhost:15672(默认账号 guest/guest 观察队列长度是否回落到 0。
  3. Task Result:上面的 result.get() 会在任务完成时返回 payload 若超时或无法连接则会抛出异常,帮助定位问题。

3. 失败排查 Checklist

  1. 环境变量CELERY_BROKER_URLCELERY_RESULT_BACKEND 是否指向 正在运行的 RabbitMQ/Redis
  2. Worker 进程docker compose ps 确认 celery_worker 状态为 Up。
  3. 队列阻塞RabbitMQ 控制台查看是否有大量消息处于 Unacked
  4. 日志级别:测试中需要捕获日志时,可使用 with self.assertLogs('api_v1.tasks', level='INFO').
  5. 自动化测试:若任务在测试里需要真实队列,请去掉 CELERY_TASK_ALWAYS_EAGER 覆盖;否则保持默认值即可同步执行。
  6. 数据库备份依赖backup_database 在 PostgreSQL 场景下需要系统可执行 pg_dump 请确保容器/宿主机已安装 PostgreSQL 客户端工具SQLite 则会使用内置 iterdump 生成 .sql

4. 常用命令速查

操作 命令
启动 worker docker compose up -d celery_worker
查看 worker 日志 docker compose logs -f celery_worker
重启 worker docker compose restart celery_worker
清空 RabbitMQ 队列 docker compose exec rabbitmq rabbitmqctl purge_queue flower(示例)
运行单个任务测试 uv run python manage.py shell -> ping_task.delay()

通过以上步骤,即可确认 Celery + RabbitMQ 在本地能够成功执行任务,并在自动化测试里保持覆盖。若需要新增业务任务,可参考 api_v1/tasks.py 的写法:使用 @shared_task,在任务内进行必要的日志记录,便于问题排查。***