08ea5fbe98
添加用户管理视图、API和状态管理文件
377 lines
14 KiB
Python
377 lines
14 KiB
Python
"""
|
|
定时任务调度器测试 - TDD Red阶段
|
|
|
|
测试定时任务的创建、调度、执行和管理功能。
|
|
"""
|
|
|
|
import pytest
|
|
import allure
|
|
import time
|
|
import threading
|
|
from typing import Any, Callable
|
|
|
|
|
|
@allure.epic("核心框架")
|
|
@allure.feature("定时任务调度器 - TDD Red阶段")
|
|
class TestTaskScheduler:
|
|
"""定时任务调度器测试类 - TDD Red阶段(期望失败)"""
|
|
|
|
@allure.title("测试任务创建和调度 - TDD Red阶段")
|
|
@allure.description("验证任务创建和基本调度功能 - 期望失败(Red)")
|
|
@allure.severity(allure.severity_level.CRITICAL)
|
|
@pytest.mark.smoke
|
|
def test_task_creation_and_scheduling(self) -> None:
|
|
"""
|
|
TDD Red阶段: 测试任务创建和调度
|
|
|
|
预期结果:
|
|
- 能够创建任务
|
|
- 能够调度任务
|
|
- 任务在指定时间执行
|
|
"""
|
|
from core.task_scheduler import TaskScheduler, Task
|
|
|
|
with allure.step("Step 1: 创建调度器"):
|
|
scheduler = TaskScheduler()
|
|
allure.attach("✅ 创建任务调度器", "步骤1", allure.attachment_type.TEXT)
|
|
|
|
with allure.step("Step 2: 创建任务"):
|
|
executed = [False]
|
|
|
|
def task_func():
|
|
executed[0] = True
|
|
|
|
task = Task(
|
|
name="test_task",
|
|
func=task_func,
|
|
interval=1 # 1秒后执行
|
|
)
|
|
allure.attach("✅ 创建任务", "步骤2", allure.attachment_type.TEXT)
|
|
|
|
with allure.step("Step 3: 调度任务"):
|
|
scheduler.schedule(task)
|
|
allure.attach("✅ 调度任务", "步骤3", allure.attachment_type.TEXT)
|
|
|
|
with allure.step("Step 4: 等待任务执行"):
|
|
time.sleep(1.5)
|
|
allure.attach(f"✅ 任务执行状态: {executed[0]}", "步骤4", allure.attachment_type.TEXT)
|
|
assert executed[0] is True, "任务应该被执行"
|
|
|
|
with allure.step("Step 5: 停止调度器"):
|
|
scheduler.stop()
|
|
|
|
@allure.title("测试周期性任务 - TDD Red阶段")
|
|
@allure.description("验证周期性任务执行 - 期望失败(Red)")
|
|
@allure.severity(allure.severity_level.CRITICAL)
|
|
@pytest.mark.smoke
|
|
def test_periodic_task(self) -> None:
|
|
"""
|
|
TDD Red阶段: 测试周期性任务
|
|
|
|
预期结果:
|
|
- 任务按周期重复执行
|
|
- 可以停止周期性任务
|
|
"""
|
|
from core.task_scheduler import TaskScheduler, Task
|
|
|
|
with allure.step("Step 1: 创建调度器"):
|
|
scheduler = TaskScheduler()
|
|
allure.attach("✅ 创建任务调度器", "步骤1", allure.attachment_type.TEXT)
|
|
|
|
with allure.step("Step 2: 创建周期性任务"):
|
|
execution_count = [0]
|
|
|
|
def periodic_task():
|
|
execution_count[0] += 1
|
|
|
|
task = Task(
|
|
name="periodic_task",
|
|
func=periodic_task,
|
|
interval=0.5, # 每0.5秒执行
|
|
repeat=True
|
|
)
|
|
allure.attach("✅ 创建周期性任务", "步骤2", allure.attachment_type.TEXT)
|
|
|
|
with allure.step("Step 3: 调度并等待"):
|
|
scheduler.schedule(task)
|
|
time.sleep(2) # 等待执行多次
|
|
allure.attach(f"✅ 执行次数: {execution_count[0]}", "步骤3", allure.attachment_type.TEXT)
|
|
assert execution_count[0] >= 3, "任务应该执行多次"
|
|
|
|
with allure.step("Step 4: 停止调度器"):
|
|
scheduler.stop()
|
|
|
|
@allure.title("测试任务取消 - TDD Green阶段")
|
|
@allure.description("验证任务取消功能")
|
|
@allure.severity(allure.severity_level.NORMAL)
|
|
@pytest.mark.regression
|
|
def test_task_cancellation(self) -> None:
|
|
"""
|
|
TDD Green阶段: 测试任务取消
|
|
|
|
预期结果:
|
|
- 可以取消已调度的任务
|
|
- 取消后任务状态变为CANCELLED
|
|
"""
|
|
from core.task_scheduler import TaskScheduler, Task, TaskStatus
|
|
|
|
with allure.step("Step 1: 创建调度器和任务"):
|
|
scheduler = TaskScheduler()
|
|
executed = [False]
|
|
|
|
def task_func():
|
|
executed[0] = True
|
|
|
|
task = Task(
|
|
name="cancellable_task",
|
|
func=task_func,
|
|
interval=10 # 很长的延迟时间
|
|
)
|
|
allure.attach("✅ 创建任务", "步骤1", allure.attachment_type.TEXT)
|
|
|
|
with allure.step("Step 2: 调度任务"):
|
|
task_id = scheduler.schedule(task)
|
|
time.sleep(0.2) # 等待调度器启动
|
|
allure.attach(f"✅ 任务已调度,ID: {task_id}", "步骤2", allure.attachment_type.TEXT)
|
|
|
|
with allure.step("Step 3: 取消任务"):
|
|
cancel_result = scheduler.cancel(task_id)
|
|
allure.attach(f"✅ 取消任务结果: {cancel_result}", "步骤3", allure.attachment_type.TEXT)
|
|
assert cancel_result is True, "取消应该成功"
|
|
|
|
with allure.step("Step 4: 验证任务状态"):
|
|
# 验证任务状态已被设置为CANCELLED
|
|
assert task.status == TaskStatus.CANCELLED, "任务状态应该为CANCELLED"
|
|
allure.attach(f"✅ 任务状态: {task.status.value}", "步骤4", allure.attachment_type.TEXT)
|
|
|
|
with allure.step("Step 5: 停止调度器"):
|
|
scheduler.stop()
|
|
|
|
@allure.title("测试任务优先级 - TDD Red阶段")
|
|
@allure.description("验证任务优先级功能 - 期望失败(Red)")
|
|
@allure.severity(allure.severity_level.NORMAL)
|
|
@pytest.mark.regression
|
|
def test_task_priority(self) -> None:
|
|
"""
|
|
TDD Red阶段: 测试任务优先级
|
|
|
|
预期结果:
|
|
- 高优先级任务先执行
|
|
- 优先级影响执行顺序
|
|
"""
|
|
from core.task_scheduler import TaskScheduler, Task
|
|
|
|
with allure.step("Step 1: 创建调度器"):
|
|
scheduler = TaskScheduler()
|
|
execution_order = []
|
|
|
|
def high_priority_task():
|
|
execution_order.append("high")
|
|
|
|
def low_priority_task():
|
|
execution_order.append("low")
|
|
|
|
allure.attach("✅ 创建调度器", "步骤1", allure.attachment_type.TEXT)
|
|
|
|
with allure.step("Step 2: 调度不同优先级任务"):
|
|
scheduler.schedule(Task(
|
|
name="low_task",
|
|
func=low_priority_task,
|
|
interval=0.1,
|
|
priority=1
|
|
))
|
|
scheduler.schedule(Task(
|
|
name="high_task",
|
|
func=high_priority_task,
|
|
interval=0.1,
|
|
priority=10
|
|
))
|
|
allure.attach("✅ 调度高低优先级任务", "步骤2", allure.attachment_type.TEXT)
|
|
|
|
with allure.step("Step 3: 等待执行"):
|
|
time.sleep(0.5)
|
|
allure.attach(f"✅ 执行顺序: {execution_order}", "步骤3", allure.attachment_type.TEXT)
|
|
|
|
with allure.step("Step 4: 停止调度器"):
|
|
scheduler.stop()
|
|
|
|
@allure.title("测试任务错误处理 - TDD Red阶段")
|
|
@allure.description("验证任务错误处理机制 - 期望失败(Red)")
|
|
@allure.severity(allure.severity_level.CRITICAL)
|
|
@pytest.mark.smoke
|
|
def test_task_error_handling(self) -> None:
|
|
"""
|
|
TDD Red阶段: 测试任务错误处理
|
|
|
|
预期结果:
|
|
- 任务异常被捕获
|
|
- 不影响其他任务执行
|
|
- 可以配置错误处理策略
|
|
"""
|
|
from core.task_scheduler import TaskScheduler, Task
|
|
|
|
with allure.step("Step 1: 创建调度器"):
|
|
scheduler = TaskScheduler()
|
|
error_handled = [False]
|
|
|
|
def error_task():
|
|
raise ValueError("测试异常")
|
|
|
|
def on_error(e):
|
|
error_handled[0] = True
|
|
|
|
allure.attach("✅ 创建调度器", "步骤1", allure.attachment_type.TEXT)
|
|
|
|
with allure.step("Step 2: 调度会失败的任务"):
|
|
task = Task(
|
|
name="error_task",
|
|
func=error_task,
|
|
interval=0.5,
|
|
on_error=on_error
|
|
)
|
|
scheduler.schedule(task)
|
|
allure.attach("✅ 调度任务", "步骤2", allure.attachment_type.TEXT)
|
|
|
|
with allure.step("Step 3: 等待并验证错误处理"):
|
|
time.sleep(1)
|
|
allure.attach(f"✅ 错误处理: {error_handled[0]}", "步骤3", allure.attachment_type.TEXT)
|
|
assert error_handled[0] is True, "错误应该被处理"
|
|
|
|
with allure.step("Step 4: 停止调度器"):
|
|
scheduler.stop()
|
|
|
|
@allure.title("测试任务统计信息 - TDD Red阶段")
|
|
@allure.description("验证任务统计信息功能 - 期望失败(Red)")
|
|
@allure.severity(allure.severity_level.NORMAL)
|
|
@pytest.mark.regression
|
|
def test_task_statistics(self) -> None:
|
|
"""
|
|
TDD Red阶段: 测试任务统计信息
|
|
|
|
预期结果:
|
|
- 记录任务执行次数
|
|
- 记录任务执行时间
|
|
- 提供统计查询接口
|
|
"""
|
|
from core.task_scheduler import TaskScheduler, Task
|
|
|
|
with allure.step("Step 1: 创建调度器"):
|
|
scheduler = TaskScheduler()
|
|
|
|
def simple_task():
|
|
pass
|
|
|
|
allure.attach("✅ 创建调度器", "步骤1", allure.attachment_type.TEXT)
|
|
|
|
with allure.step("Step 2: 调度任务并执行"):
|
|
task = Task(
|
|
name="stats_task",
|
|
func=simple_task,
|
|
interval=0.3,
|
|
repeat=True
|
|
)
|
|
scheduler.schedule(task)
|
|
time.sleep(1)
|
|
allure.attach("✅ 任务执行中", "步骤2", allure.attachment_type.TEXT)
|
|
|
|
with allure.step("Step 3: 获取统计信息"):
|
|
stats = scheduler.get_stats()
|
|
allure.attach(f"✅ 统计信息: {stats}", "步骤3", allure.attachment_type.TEXT)
|
|
assert "total_executions" in stats, "应该有执行次数统计"
|
|
|
|
with allure.step("Step 4: 停止调度器"):
|
|
scheduler.stop()
|
|
|
|
@allure.title("测试延迟任务 - TDD Red阶段")
|
|
@allure.description("验证延迟任务执行 - 期望失败(Red)")
|
|
@allure.severity(allure.severity_level.NORMAL)
|
|
@pytest.mark.regression
|
|
def test_delayed_task(self) -> None:
|
|
"""
|
|
TDD Red阶段: 测试延迟任务
|
|
|
|
预期结果:
|
|
- 任务在指定延迟后执行
|
|
- 延迟时间准确
|
|
"""
|
|
from core.task_scheduler import TaskScheduler, Task
|
|
|
|
with allure.step("Step 1: 创建调度器"):
|
|
scheduler = TaskScheduler()
|
|
executed = [False]
|
|
|
|
def delayed_task():
|
|
executed[0] = True
|
|
|
|
allure.attach("✅ 创建调度器", "步骤1", allure.attachment_type.TEXT)
|
|
|
|
with allure.step("Step 2: 调度延迟任务"):
|
|
task = Task(
|
|
name="delayed_task",
|
|
func=delayed_task,
|
|
delay=1.5 # 延迟1.5秒执行
|
|
)
|
|
scheduler.schedule(task)
|
|
allure.attach("✅ 调度延迟任务(1.5s)", "步骤2", allure.attachment_type.TEXT)
|
|
|
|
with allure.step("Step 3: 验证延迟执行"):
|
|
time.sleep(0.5)
|
|
assert executed[0] is False, "延迟时间内不应该执行"
|
|
time.sleep(1.5)
|
|
assert executed[0] is True, "延迟后应该执行"
|
|
allure.attach("✅ 延迟执行验证通过", "步骤3", allure.attachment_type.TEXT)
|
|
|
|
with allure.step("Step 4: 停止调度器"):
|
|
scheduler.stop()
|
|
|
|
@allure.title("测试调度器状态管理 - TDD Red阶段")
|
|
@allure.description("验证调度器状态管理功能 - 期望失败(Red)")
|
|
@allure.severity(allure.severity_level.NORMAL)
|
|
@pytest.mark.regression
|
|
def test_scheduler_state_management(self) -> None:
|
|
"""
|
|
TDD Red阶段: 测试调度器状态管理
|
|
|
|
预期结果:
|
|
- 可以暂停调度器
|
|
- 可以恢复调度器
|
|
- 可以获取当前状态
|
|
"""
|
|
from core.task_scheduler import TaskScheduler, Task
|
|
|
|
with allure.step("Step 1: 创建调度器"):
|
|
scheduler = TaskScheduler()
|
|
execution_count = [0]
|
|
|
|
def counting_task():
|
|
execution_count[0] += 1
|
|
|
|
allure.attach("✅ 创建调度器", "步骤1", allure.attachment_type.TEXT)
|
|
|
|
with allure.step("Step 2: 调度周期性任务"):
|
|
task = Task(
|
|
name="counting_task",
|
|
func=counting_task,
|
|
interval=0.5,
|
|
repeat=True
|
|
)
|
|
scheduler.schedule(task)
|
|
time.sleep(1)
|
|
allure.attach(f"✅ 执行次数: {execution_count[0]}", "步骤2", allure.attachment_type.TEXT)
|
|
|
|
with allure.step("Step 3: 暂停调度器"):
|
|
scheduler.pause()
|
|
count_before = execution_count[0]
|
|
time.sleep(1)
|
|
assert execution_count[0] == count_before, "暂停后不应该执行"
|
|
allure.attach("✅ 暂停成功", "步骤3", allure.attachment_type.TEXT)
|
|
|
|
with allure.step("Step 4: 恢复调度器"):
|
|
scheduler.resume()
|
|
time.sleep(0.6)
|
|
assert execution_count[0] > count_before, "恢复后应该继续执行"
|
|
allure.attach("✅ 恢复成功", "步骤4", allure.attachment_type.TEXT)
|
|
|
|
with allure.step("Step 5: 停止调度器"):
|
|
scheduler.stop()
|