| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335 |
- """
- 巡检管理核心流程单元测试
- 覆盖任务创建、分配、执行和上报流程
- """
- import unittest
- from unittest.mock import Mock, patch, MagicMock
- from datetime import datetime, timedelta
- import json
- from src.inspection.models import InspectionTask, InspectionReport
- from src.inspection.services import TaskService, ExecutionService, ReportService
-
-
- class TestInspectionTask(unittest.TestCase):
- """巡检任务模型测试"""
-
- def setUp(self):
- self.task_data = {
- "task_id": "inspection_001",
- "title": "设备巡检任务",
- "description": "检查所有传感器设备状态",
- "device_ids": ["sensor_001", "sensor_002", "sensor_003"],
- "assigned_to": "inspector_01",
- "scheduled_time": "2026-06-17T09:00:00Z",
- "duration_minutes": 60,
- "priority": "high",
- "status": "pending"
- }
-
- def test_task_creation(self):
- """测试任务创建"""
- task = InspectionTask(self.task_data)
-
- self.assertEqual(task.task_id, self.task_data["task_id"])
- self.assertEqual(task.title, self.task_data["title"])
- self.assertEqual(len(task.device_ids), 3)
- self.assertEqual(task.status, "pending")
-
- # 验证时间格式
- self.assertTrue(datetime.fromisoformat(task.scheduled_time))
-
- def test_task_validation(self):
- """测试任务验证"""
- valid_task = InspectionTask(self.task_data)
- result = valid_task.validate()
- self.assertTrue(result["valid"])
-
- # 测试无效任务
- invalid_task_data = self.task_data.copy()
- invalid_task_data["device_ids"] = [] # 空设备列表
- invalid_task = InspectionTask(invalid_task_data)
- result = invalid_task.validate()
- self.assertFalse(result["valid"])
-
- def test_task_status_transitions(self):
- """测试任务状态转换"""
- task = InspectionTask(self.task_data)
-
- # 从pending到assigned
- task.assign_to("inspector_02")
- self.assertEqual(task.status, "assigned")
- self.assertEqual(task.assigned_to, "inspector_02")
-
- # 从assigned到in_progress
- task.start_execution()
- self.assertEqual(task.status, "in_progress")
- self.assertIsNotNone(task.started_at)
-
- # 从in_progress到completed
- task.complete_execution()
- self.assertEqual(task.status, "completed")
- self.assertIsNotNone(task.completed_at)
-
-
- class TestTaskService(unittest.TestCase):
- """任务服务测试"""
-
- def setUp(self):
- self.task_service = TaskService()
-
- @patch('src.inspection.services.session')
- def test_create_inspection_task(self, mock_session):
- """测试创建巡检任务"""
- task_data = {
- "task_id": "inspection_001",
- "title": "设备巡检",
- "device_ids": ["sensor_001", "sensor_002"],
- "scheduled_time": "2026-06-17T09:00:00Z"
- }
-
- with patch.object(self.task_service, 'save_task') as mock_save:
- mock_save.return_value = {"success": True, "task_id": "inspection_001"}
-
- result = self.task_service.create_task(task_data)
- self.assertTrue(result["success"])
- mock_save.assert_called_once()
-
- @patch('src.inspection.services.session')
- def test_assign_task(self, mock_session):
- """测试任务分配"""
- task_id = "inspection_001"
- inspector_id = "inspector_01"
-
- with patch.object(self.task_service, 'update_task') as mock_update:
- mock_update.return_value = {"success": True}
-
- result = self.task_service.assign_task(task_id, inspector_id)
- self.assertTrue(result["success"])
- mock_update.assert_called_once()
-
- @patch('src.inspection.services.session')
- def test_get_pending_tasks(self, mock_session):
- """测试获取待处理任务"""
- with patch.object(self.task_service, 'query_tasks') as mock_query:
- mock_query.return_value = [
- {"task_id": "task_001", "status": "pending"},
- {"task_id": "task_002", "status": "pending"}
- ]
-
- tasks = self.task_service.get_pending_tasks()
- self.assertEqual(len(tasks), 2)
- mock_query.assert_called_with(status="pending")
-
- def test_task_scheduling_conflict(self):
- """测试任务调度冲突检测"""
- task1 = {
- "task_id": "task_001",
- "scheduled_time": "2026-06-17T09:00:00Z",
- "duration_minutes": 60
- }
-
- task2 = {
- "task_id": "task_002",
- "scheduled_time": "2026-06-17T09:30:00Z",
- "duration_minutes": 60
- }
-
- # 这两个任务有时间冲突
- has_conflict = self.task_service.check_scheduling_conflict(task1, task2)
- self.assertTrue(has_conflict)
-
- # 不冲突的任务
- task3 = {
- "task_id": "task_003",
- "scheduled_time": "2026-06-17T11:00:00Z",
- "duration_minutes": 60
- }
-
- has_conflict = self.task_service.check_scheduling_conflict(task1, task3)
- self.assertFalse(has_conflict)
-
-
- class TestExecutionService(unittest.TestCase):
- """执行服务测试"""
-
- def setUp(self):
- self.execution_service = ExecutionService()
-
- @patch('src.inspection.services.DeviceService')
- def test_start_inspection_execution(self, mock_device_service):
- """测试开始巡检执行"""
- task_id = "inspection_001"
- inspector_id = "inspector_01"
-
- mock_device_service.return_value.check_device_availability.return_value = True
-
- result = self.execution_service.start_execution(task_id, inspector_id)
- self.assertTrue(result["success"])
- self.assertEqual(result["status"], "in_progress")
-
- @patch('src.inspection.services.DeviceService')
- def test_inspection_execution_flow(self, mock_device_service):
- """测试巡检执行流程"""
- task_id = "inspection_001"
-
- # 模拟设备检查
- mock_device_service.return_value.check_device_availability.return_value = True
- mock_device_service.return_value.perform_diagnostic.return_value = {
- "status": "normal",
- "metrics": {"temperature": 25.5, "humidity": 60.2}
- }
-
- # 执行巡检
- execution_result = self.execution_service.execute_inspection(task_id)
-
- self.assertTrue(execution_result["success"])
- self.assertIn("device_results", execution_result)
- self.assertIn("execution_time", execution_result)
-
- def test_inspection_timeout_handling(self):
- """测试巡检超时处理"""
- task_id = "inspection_001"
-
- # 模拟长时间运行的巡检
- with patch.object(self.execution_service, 'execute_inspection') as mock_execute:
- mock_execute.return_value = {
- "success": False,
- "error": "Execution timeout",
- "timeout_seconds": 300
- }
-
- result = self.execution_service.execute_inspection(task_id, timeout_seconds=30)
- self.assertFalse(result["success"])
- self.assertIn("timeout", result["error"])
-
-
- class TestReportService(unittest.TestCase):
- """报告服务测试"""
-
- def setUp(self):
- self.report_service = ReportService()
-
- @patch('src.inspection.services.session')
- def test_create_inspection_report(self, mock_session):
- """测试创建巡检报告"""
- task_id = "inspection_001"
- report_data = {
- "summary": "设备巡检完成",
- "findings": [
- {"device_id": "sensor_001", "status": "normal", "notes": "运行正常"},
- {"device_id": "sensor_002", "status": "warning", "notes": "温度偏高"}
- ],
- "recommendations": ["建议检查散热系统"]
- }
-
- with patch.object(self.report_service, 'save_report') as mock_save:
- mock_save.return_value = {"success": True, "report_id": "report_001"}
-
- result = self.report_service.create_report(task_id, report_data)
- self.assertTrue(result["success"])
- mock_save.assert_called_once()
-
- @patch('src.inspection.services.session')
- def test_get_inspection_history(self, mock_session):
- """测试获取巡检历史"""
- inspector_id = "inspector_01"
- start_date = "2026-06-01"
- end_date = "2026-06-16"
-
- with patch.object(self.report_service, 'query_reports') as mock_query:
- mock_query.return_value = [
- {"task_id": "task_001", "date": "2026-06-15", "status": "completed"},
- {"task_id": "task_002", "date": "2026-06-14", "status": "completed"}
- ]
-
- reports = self.report_service.get_inspection_history(
- inspector_id, start_date, end_date
- )
- self.assertEqual(len(reports), 2)
- mock_query.assert_called_with(inspector_id, start_date, end_date)
-
- def test_report_validation(self):
- """测试报告验证"""
- report_data = {
- "task_id": "inspection_001",
- "summary": "巡检完成",
- "findings": [
- {"device_id": "sensor_001", "status": "normal"},
- {"device_id": "sensor_002", "status": "warning"}
- ]
- }
-
- result = self.report_service.validate_report(report_data)
- self.assertTrue(result["valid"])
-
- # 测试无效报告(缺少必需字段)
- invalid_report = {"summary": " incomplete report"}
- result = self.report_service.validate_report(invalid_report)
- self.assertFalse(result["valid"])
-
-
- class TestInspectionReport(unittest.TestCase):
- """巡检报告模型测试"""
-
- def setUp(self):
- self.report_data = {
- "report_id": "report_001",
- "task_id": "inspection_001",
- "inspector_id": "inspector_01",
- "summary": "设备巡检完成",
- "start_time": "2026-06-17T09:00:00Z",
- "end_time": "2026-06-17T10:30:00Z",
- "findings": [
- {"device_id": "sensor_001", "status": "normal", "notes": "运行正常"},
- {"device_id": "sensor_002", "status": "warning", "notes": "温度偏高"}
- ],
- "recommendations": ["检查散热系统", "校准传感器"],
- "overall_status": "warning"
- }
-
- def test_report_creation(self):
- """测试报告创建"""
- report = InspectionReport(self.report_data)
-
- self.assertEqual(report.report_id, self.report_data["report_id"])
- self.assertEqual(report.task_id, self.report_data["task_id"])
- self.assertEqual(len(report.findings), 2)
- self.assertEqual(report.overall_status, "warning")
-
- # 验证时间
- self.assertTrue(datetime.fromisoformat(report.start_time))
- self.assertTrue(datetime.fromisoformat(report.end_time))
-
- def test_report_status_calculation(self):
- """测试报告状态计算"""
- report = InspectionReport(self.report_data)
-
- # 基于发现的问题计算整体状态
- calculated_status = report.calculate_overall_status()
- self.assertEqual(calculated_status, "warning")
-
- # 修改为正常状态
- report.findings = [{"device_id": "sensor_001", "status": "normal"}]
- calculated_status = report.calculate_overall_status()
- self.assertEqual(calculated_status, "normal")
-
- def test_report_export(self):
- """测试报告导出"""
- report = InspectionReport(self.report_data)
-
- # 导出为JSON
- json_export = report.export_to_json()
- self.assertEqual(json_export["report_id"], self.report_data["report_id"])
-
- # 导出为CSV
- csv_export = report.export_to_csv()
- self.assertIn("device_id,status,notes", csv_export)
-
- # 导出为PDF(模拟)
- pdf_export = report.export_to_pdf()
- self.assertIsNotNone(pdf_export)
- self.assertIn("设备巡检报告", pdf_export)
-
-
- if __name__ == '__main__':
- unittest.main()
|