""" 定时任务调度器测试 - 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()