
大家期待已久的星球专属版,今天终于迎来了正式发布!严格来说,这次不是对 TestHub 测试平台做一些简单的功能升级,而是进行了一次深度重构,从原来的 Celery 异步任务架构 升级到 Django-Q2 任务队列架构,同时新增了性能监控、通知模板系统等多个企业级功能,另外对UI自动化测试、AI智能测试等模块也做了优化提升。
今天就来详细聊聊这次重构的核心变化和升级点。
原架构痛点:
原项目依赖:192 行 requirements.txt
新项目依赖:49 行 requirements.txt核心优势:
对比项 | Celery | Django-Q2 |
|---|---|---|
配置复杂度 | 高(需配置 Broker) | 低(Django 内置配置) |
部署难度 | 需要独立启动 Worker | 一条命令 python manage.py qcluster |
依赖数量 | 多(redis/celery/billiard) | 少(django-q2 + redis) |
任务监控 | 需要额外安装 Flower | Admin 后台自带监控 |
内存占用 | 较高 | 较低 |
启动方式对比:
# 原 Celery 方式
celery -A backend worker -l info --pool=solo
# 新 Django-Q2 方式(也可以通过项目的start.sh脚本一键启动)
python manage.py qcluster在测试平台运行过程中,经常会遇到这样的问题:
这次我们新增了完整的性能监控系统,包含两个核心模型:
class RequestPerformanceLog(models.Model):
path = models.CharField(max_length=500, verbose_name='请求路径')
method = models.CharField(max_length=10, verbose_name='请求方法')
response_time = models.FloatField(verbose_name='响应时间(ms)')
status_code = models.IntegerField(verbose_name='状态码')
user = models.ForeignKey(User, on_delete=models.SET_NULL, null=True)
ip_address = models.GenericIPAddressField(null=True, blank=True)
user_agent = models.CharField(max_length=500, blank=True)
created_at = models.DateTimeField(auto_now_add=True)记录内容:
class PerformanceStatistics(models.Model):
date = models.DateField(unique=True, verbose_name='日期')
total_requests = models.IntegerField(default=0, verbose_name='总请求数')
avg_response_time = models.FloatField(default=0, verbose_name='平均响应时间(ms)')
max_response_time = models.FloatField(default=0, verbose_name='最大响应时间(ms)')
min_response_time = models.FloatField(default=0, verbose_name='最小响应时间(ms)')
error_count = models.IntegerField(default=0, verbose_name='错误请求数')
slow_requests = models.IntegerField(default=0, verbose_name='慢请求数(>1s)')统计指标:
新增 admin_performance.py,提供可视化的性能监控界面:
系统创建了两个定时任务:
# 每日凌晨聚合前一天的性能数据
Schedule.objects.create(
name='每日性能统计聚合',
func='apps.core.tasks.aggregate_daily_performance_stats',
schedule_type='D',
next_run=now() + timedelta(days=1),
repeats=-1 # 永久重复
)
# 每30分钟聚合当天的实时数据
Schedule.objects.create(
name='实时性能统计聚合',
func='apps.core.tasks.aggregate_realtime_performance_stats',
schedule_type='I',
minutes=30,
repeats=-1
)

原项目通知功能存在以下限制:
新增了 NotificationTemplate 模型:
class NotificationTemplate(models.Model):
TEMPLATE_TYPE_CHOICES = [
('markdown', 'Markdown'),
('html', 'HTML'),
('text', '纯文本'),
]
name = models.CharField(max_length=100, verbose_name='模板名称')
template_type = models.CharField(max_length=20, choices=TEMPLATE_TYPE_CHOICES)
subject = models.CharField(max_length=200, blank=True, verbose_name='邮件主题')
content = models.TextField(verbose_name='模板内容')
variables = models.JSONField(default=list, blank=True, verbose_name='模板变量')
is_default = models.BooleanField(default=False, verbose_name='是否默认模板')
is_active = models.BooleanField(default=True, verbose_name='是否启用')支持的变量替换:
# 定时任务相关变量
{{task_name}} # 任务名称
{{status_text}} # 执行状态(成功/失败)
{{execution_time}} # 执行时间
{{task_type}} # 任务类型
# 测试执行相关变量
{{title}} # 测试标题
{{tester}} # 测试人员
{{total_cases}} # 用例总数
{{passed_cases}} # 通过用例数
{{failed_cases}} # 失败用例数
{{error_cases}} # 错误用例数
{{skipped_cases}} # 跳过用例数
{{runtime}} # 执行时长
{{begin_time}} # 开始时间新增了邮件通知支持:
class UnifiedNotificationConfig(models.Model):
# 原有配置
webhook_url = models.URLField(max_length=500, blank=True)
secret = models.CharField(max_length=200, blank=True)
# 新增邮件配置
email_recipients = models.JSONField(default=list, blank=True)
email_attach_report = models.BooleanField(default=False)
# 关联通知模板
notification_template = models.ForeignKey(
'NotificationTemplate',
on_delete=models.SET_NULL,
null=True,
blank=True
)邮件收件人支持两种格式:
进入后台管理-核心模块-通知模板进行配置

原项目定时任务分散在各个模块中(api_testing、ui_automation),存在以下问题:
scheduler/
├── admin.py # Admin 后台配置
├── apps.py # 应用配置
├── migrations/ # 数据库迁移
├── models.py # ScheduleConfig 扩展模型
├── serializers.py # API 序列化器
├── task_executor.py # 统一任务执行器(33785行)
├── urls.py # API 路由
└── views.py # API 视图扩展 Django-Q 的 Schedule 模型,增加业务配置:
class ScheduleConfig(models.Model):
MODULE_CHOICES = [
('API', 'API测试'),
('UI', 'UI自动化'),
('APP', 'APP自动化'),
]
TASK_TYPE_CHOICES = [
('API_TEST_SUITE', 'API测试套件'),
('API_REQUEST', 'API请求'),
('UI_TEST_SUITE', 'UI测试套件'),
('UI_TEST_CASE', 'UI测试用例'),
('APP_TEST_SUITE', 'APP测试套件'),
('APP_TEST_CASE', 'APP测试用例'),
]
schedule = models.OneToOneField(Schedule, ...)
module = models.CharField(max_length=20, choices=MODULE_CHOICES)
task_type = models.CharField(max_length=30, choices=TASK_TYPE_CHOICES)
project_id = models.IntegerField()
target_id = models.IntegerField()
environment_id = models.IntegerField()
task_config = models.JSONField(default=dict)
# 通知配置
notify_on_success = models.BooleanField(default=False)
notify_on_failure = models.BooleanField(default=True)
notify_on_email = models.BooleanField(default=False)
notify_on_webhook = models.BooleanField(default=False)
notification_configs = models.ManyToManyField('core.UnifiedNotificationConfig')
notification_template = models.ForeignKey('core.NotificationTemplate', ...)
# 统计信息
last_run_time = models.DateTimeField(null=True, blank=True)
success_count = models.IntegerField(default=0)
failure_count = models.IntegerField(default=0)def create_scheduled_task(
name,
module,
task_type,
schedule_type,
target_id=None,
project_id=None,
environment_id=None,
task_config=None,
cron=None,
minutes=None,
notification_template=None,
...
):
"""创建定时任务的统一入口"""
func = get_task_function(task_type)
schedule = Schedule.objects.create(
name=name,
func=func,
schedule_type=schedule_type,
cron=cron,
minutes=minutes,
...
)
config = ScheduleConfig.objects.create(...)
return schedule, configdef pause(self):
"""暂停任务"""
self.status = 'PAUSED'
self.schedule.next_run = None
self.save()
def resume(self):
"""恢复任务"""
self.status = 'ACTIVE'
self.schedule.next_run = timezone.now()
self.save()
def execute_now(self):
"""立即执行任务"""
from apps.scheduler.task_executor import execute_task
return execute_task(self.schedule_id)原项目配置分散:
backend/.envfrontend/.env新增统一配置文件 config.yaml:
# 服务端口配置
server:
frontend_port: 3000
backend_port: 8000
backend_host: "127.0.0.1"
frontend_url: "http://localhost:3000"
# 数据库配置
database:
name: testhub
user: root
password: ""
host: "127.0.0.1"
port: 3306
# Redis 配置
redis:
url: "redis://127.0.0.1:6379/"
redis_db: 0
cache_db: 1
session_db: 2
# JWT 配置
jwt:
access_token_lifetime: 30
refresh_token_lifetime: 7testhub_platform/
├── apps/ # Django 应用(根目录)
├── backend/ # Django 配置
├── frontend/ # Vue 前端
├── manage.py
└── requirements.txttesthub_platform/
├── backend/
│ ├── apps/ # Django 应用(移到 backend 下)
│ ├── backend/ # Django 配置
│ ├── manage.py # 管理脚本
│ ├── requirements.txt # Python 依赖
│ ├── start.sh # 启动脚本
│ └── start.bat # Windows 启动脚本
├── frontend/ # Vue 前端
├── config.yaml # 统一配置文件 ⭐
├── expand/ # 扩展工具
│ └── allure/ # Allure 测试报告
└── docs/ # 文档目录结构变化的意义:
本次我们将主框架Django由4.2.7升级到了6.0,不仅性能上得到提升,将来也可以支持更多新特性。
技术组件 | 原版本 | 新版本 | 升级说明 |
|---|---|---|---|
Django | 4.2.7 | 6.0.2 | 性能提升、新特性 |
Celery | 5.3.4 | ❌ 移除 | 替换为 Django-Q2 |
django-q2 | ❌ | 1.6.0+ | 轻量级任务队列 |
mysqlclient | 2.2.7 | 2.2.7 | 保持不变 |
PyMySQL | 1.1.0 | pymysql>=1.1.2 | 版本更新 |
首先是依赖包减少了,原来项目192行依赖,经常有同学反馈安装过程中各种依赖报错、冲突。针对于这个问题,我们这次升级后,依赖包减少到了只有49行,安装更快捷。
requirements.txt 从 192 行精简到 49 行
减少了约 75% 的依赖包这次我们调整了迁移文件上传策略,遵循Django最佳规范,将所有生成的数据迁移文件都同时上传。也就是说大家无需再手动创建迁移文件,后续只要有表结构变动,只需执行“python manage.py migrate”迁移数据即可。

原部署步骤,在开发模式下,要分别启动4个服务窗口:
1. 启动前端
2. 启动 Django Server
3. 启动 Celery Worker
4. 启动定时任务 scheduler而在新部署步骤下,只需通过./start.sh脚本一键启动聚合后台(windows系统为.\start.bat),且无需激活虚拟环境,大大简化了启动步骤。
1. 启动前端
2. 启动聚合后台:Django Server + Django-Q + Scheduler 
之前想要修改前后台端口号需要分别修改前后端配置文件,这次做了集成,在config.yaml配置文件中即可统一修改:
server:
# 前端服务端口(开发环境)
frontend_port: 3001
# 后端服务端口(开发环境)
backend_port: 8001
# 后端服务主机地址
backend_host: "127.0.0.1"
# 是否启用后端debug
debug: false
# 后端SECRET_KEY,可使用backend/docs/key.py生成
secret_key: xxxxxxx之前有小伙伴在群里反馈,页面及元素太多时,无法筛选,所以这次新增了根据页面选择以及元素名称筛选元素功能。

之前有小伙伴反馈,想要在执行UI自动化操作时跳转到指定URL,这次也安排上了!

另外,为了便于大家快捷添加、删除、管理元素,这次特地加了一键复制、删除和拖拽功能。

既然前面加了URL跳转,那根据URL断言也不可少。

新建元素页面也做了优化,各个字段增加必填项展示和脱焦校验,体验更友好。

得益于Django-Q,触发器能够完美支持每小时、每天、每周、每月、每年等等。

本次 TestHub 星球专属版的发布,不是一次简单的迭代,而是一次从底层架构到用户体验的深度革新。简单来说,这次更新就干了三件大事:让部署更省心、让功能更实用、让操作更顺手。
以前搭环境总被复杂的依赖和配置劝退,现在换了 Django-Q2,依赖少了一大截,一个脚本就能启动,大大降低了“从入门到放弃”的概率。新加的性能监控和通知模板,也都是咱们平时工作中真正痛的点和刚需——哪个接口慢、报告怎么发,现在都能灵活配置,不再是一笔糊涂账。再加上 UI 和 AI 模块的各种细节优化,整个平台用起来明显更“跟手”了。
总之,这次升级没整那些虚的,全是奔着解决实际问题去的。更多功能就不一一介绍了,欢迎大家自行体验~
部署过程详见README文档哦!
特别提醒:这次的星球版有别于开源版,是属于星球付费用户的专属版本,两者是独立的项目。已付费的成员请私聊我获取项目地址,开通代码权限。