| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298 |
- import pytest
- import sys
- import os
- from unittest.mock import MagicMock, patch
- from flask import json
- from flask_socketio import SocketIOTestClient
- # 添加项目根目录到Python路径
- sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
- from app import app, socketio, serial_client, mqtt_client
- class TestApp:
-
- def setup_method(self):
- """每个测试方法执行前的设置"""
- # 创建Flask测试客户端
- self.client = app.test_client()
- app.config['TESTING'] = True
-
- # 创建SocketIO测试客户端
- self.socketio_client = SocketIOTestClient(app, socketio)
-
- # 模拟串口客户端和MQTT客户端
- self.mock_serial = patch('app.serial_client').start()
- self.mock_mqtt = patch('app.mqtt_client').start()
-
- # 模拟初始状态
- self.mock_serial.get_status.return_value = False
- self.mock_mqtt.get_status.return_value = False
-
- def teardown_method(self):
- """每个测试方法执行后的清理"""
- # 停止所有模拟
- patch.stopall()
- # 断开SocketIO连接
- self.socketio_client.disconnect()
-
- def test_serial_connect_api(self):
- """测试串口连接API"""
- # 模拟连接成功
- self.mock_serial.connect.return_value = (True, "串口连接成功")
-
- # 发送POST请求
- response = self.client.post('/api/serial/connect',
- data=json.dumps({
- 'port': 'COM1',
- 'baudrate': 9600
- }),
- content_type='application/json')
-
- # 验证响应
- assert response.status_code == 200
- data = json.loads(response.data)
- assert data['success'] is True
- assert data['message'] == "串口连接成功"
-
- # 验证调用
- self.mock_serial.connect.assert_called_once_with('COM1', 9600)
-
- def test_serial_disconnect_api(self):
- """测试串口断开连接API"""
- # 发送POST请求
- response = self.client.post('/api/serial/disconnect')
-
- # 验证响应
- assert response.status_code == 200
- data = json.loads(response.data)
- assert data['success'] is True
- assert data['message'] == "串口已断开"
-
- # 验证调用
- self.mock_serial.disconnect.assert_called_once()
-
- def test_serial_status_api(self):
- """测试获取串口状态API"""
- # 模拟串口已连接
- self.mock_serial.get_status.return_value = True
-
- # 发送GET请求
- response = self.client.get('/api/serial/status')
-
- # 验证响应
- assert response.status_code == 200
- data = json.loads(response.data)
- assert data['connected'] is True
-
- def test_serial_send_api(self):
- """测试串口发送数据API"""
- # 模拟发送成功
- self.mock_serial.send_data.return_value = (True, "数据发送成功")
-
- # 发送POST请求
- response = self.client.post('/api/serial/send',
- data=json.dumps({
- 'data': 'test message'
- }),
- content_type='application/json')
-
- # 验证响应
- assert response.status_code == 200
- data = json.loads(response.data)
- assert data['success'] is True
-
- # 验证调用
- self.mock_serial.send_data.assert_called_once_with('test message')
-
- def test_mqtt_connect_api(self):
- """测试MQTT连接API"""
- # 模拟连接成功
- self.mock_mqtt.connect.return_value = (True, "MQTT连接成功")
-
- # 发送POST请求
- mqtt_config = {
- 'broker': 'localhost',
- 'port': 1883,
- 'username': '',
- 'password': '',
- 'client_id': 'test_client',
- 'keepalive': 60,
- 'use_tls': False
- }
- response = self.client.post('/api/mqtt/connect',
- data=json.dumps(mqtt_config),
- content_type='application/json')
-
- # 验证响应
- assert response.status_code == 200
- data = json.loads(response.data)
- assert data['success'] is True
- assert data['message'] == "MQTT连接成功"
-
- # 验证调用
- self.mock_mqtt.connect.assert_called_once_with(mqtt_config)
-
- def test_mqtt_disconnect_api(self):
- """测试MQTT断开连接API"""
- # 发送POST请求
- response = self.client.post('/api/mqtt/disconnect')
-
- # 验证响应
- assert response.status_code == 200
- data = json.loads(response.data)
- assert data['success'] is True
- assert data['message'] == "MQTT已断开"
-
- # 验证调用
- self.mock_mqtt.disconnect.assert_called_once()
-
- def test_mqtt_status_api(self):
- """测试获取MQTT状态API"""
- # 模拟MQTT已连接
- self.mock_mqtt.get_status.return_value = True
-
- # 发送GET请求
- response = self.client.get('/api/mqtt/status')
-
- # 验证响应
- assert response.status_code == 200
- data = json.loads(response.data)
- assert data['connected'] is True
-
- def test_mqtt_publish_api(self):
- """测试MQTT发布消息API"""
- # 模拟发布成功
- self.mock_mqtt.publish.return_value = (True, "消息发布成功")
-
- # 发送POST请求
- response = self.client.post('/api/mqtt/publish',
- data=json.dumps({
- 'topic': 'test/topic',
- 'message': 'test message'
- }),
- content_type='application/json')
-
- # 验证响应
- assert response.status_code == 200
- data = json.loads(response.data)
- assert data['success'] is True
-
- # 验证调用
- self.mock_mqtt.publish.assert_called_once_with('test/topic', 'test message')
-
- def test_mqtt_subscribe_api(self):
- """测试MQTT订阅主题API"""
- # 模拟订阅成功
- self.mock_mqtt.subscribe.return_value = (True, "主题订阅成功")
-
- # 发送POST请求
- response = self.client.post('/api/mqtt/subscribe',
- data=json.dumps({
- 'topic': 'test/topic'
- }),
- content_type='application/json')
-
- # 验证响应
- assert response.status_code == 200
- data = json.loads(response.data)
- assert data['success'] is True
-
- # 验证调用
- self.mock_mqtt.subscribe.assert_called_once_with('test/topic')
-
- def test_get_serial_data_api(self):
- """测试获取串口数据API"""
- # 发送GET请求
- response = self.client.get('/api/data/serial')
-
- # 验证响应
- assert response.status_code == 200
- data = json.loads(response.data)
- assert isinstance(data, list)
-
- def test_get_mqtt_data_api(self):
- """测试获取MQTT数据API"""
- # 发送GET请求
- response = self.client.get('/api/data/mqtt')
-
- # 验证响应
- assert response.status_code == 200
- data = json.loads(response.data)
- assert isinstance(data, list)
-
- def test_forward_config_api(self):
- """测试设置转发配置API"""
- # 发送POST请求
- response = self.client.post('/api/forward/config',
- data=json.dumps({
- 'serial_to_mqtt': True,
- 'mqtt_to_serial': False,
- 'publish_topic': 'serial/data'
- }),
- content_type='application/json')
-
- # 验证响应
- assert response.status_code == 200
- data = json.loads(response.data)
- assert data['success'] is True
- assert data['message'] == "转发配置已更新"
-
- def test_get_forward_status_api(self):
- """测试获取转发状态API"""
- # 发送GET请求
- response = self.client.get('/api/forward/status')
-
- # 验证响应
- assert response.status_code == 200
- data = json.loads(response.data)
- assert 'serial_to_mqtt' in data
- assert 'mqtt_to_serial' in data
- assert 'publish_topic' in data
-
- def test_health_check_api(self):
- """测试健康检查API"""
- # 发送GET请求
- response = self.client.get('/api/health')
-
- # 验证响应
- assert response.status_code == 200
- data = json.loads(response.data)
- assert data['status'] == 'healthy'
- assert 'timestamp' in data
- assert 'services' in data
-
- def test_socketio_data_namespace(self):
- """测试数据命名空间的WebSocket连接"""
- # 连接到数据命名空间
- self.socketio_client.connect(namespace='/data')
-
- # 验证连接成功
- received = self.socketio_client.get_received('/data')
- # 应该收到历史数据事件
- events = [event['name'] for event in received]
- assert 'serial_data_history' in events or 'mqtt_data_history' in events
-
- # 断开连接
- self.socketio_client.disconnect(namespace='/data')
-
- def test_socketio_status_namespace(self):
- """测试状态命名空间的WebSocket连接"""
- # 连接到状态命名空间
- self.socketio_client.connect(namespace='/status')
-
- # 验证连接成功
- received = self.socketio_client.get_received('/status')
- # 应该收到当前状态事件
- events = [event['name'] for event in received]
- assert 'serial_status' in events
- assert 'mqtt_status' in events
- assert 'forward_status' in events
-
- # 断开连接
- self.socketio_client.disconnect(namespace='/status')
- if __name__ == "__main__":
- pytest.main(["-v", __file__])
|