refactor(test): 重构测试套件结构并优化测试配置
feat(test-suite): 新增测试套件模块,包含API测试客户端和测试配置 fix(api): 修复数据库实体和仓库的删除操作返回值 style(api): 统一数据库表名和字段命名 perf(api): 添加缓存注解提升配置查询性能 test(api): 添加H2测试数据库配置支持 chore: 清理旧的测试文件和脚本
This commit is contained in:
@@ -0,0 +1,191 @@
|
||||
"""
|
||||
WebSocket实时通信测试用例
|
||||
"""
|
||||
|
||||
import pytest
|
||||
import asyncio
|
||||
import json
|
||||
import os
|
||||
from websockets.client import connect
|
||||
from websockets.exceptions import ConnectionClosed
|
||||
|
||||
|
||||
@pytest.mark.websocket
|
||||
@pytest.mark.regression
|
||||
class TestWebSocket:
|
||||
"""WebSocket实时通信测试类"""
|
||||
|
||||
@pytest.fixture
|
||||
def websocket_url(self):
|
||||
"""WebSocket连接URL"""
|
||||
api_base_url = os.getenv("API_BASE_URL", "http://localhost:8084")
|
||||
ws_url = api_base_url.replace("http://", "ws://")
|
||||
return f"{ws_url}/ws"
|
||||
|
||||
@pytest.fixture
|
||||
async def websocket_connection(self, websocket_url):
|
||||
"""WebSocket连接fixture"""
|
||||
async with connect(websocket_url) as websocket:
|
||||
yield websocket
|
||||
|
||||
@pytest.fixture
|
||||
async def authenticated_websocket(self, websocket_url, authenticated_client):
|
||||
"""带认证的WebSocket连接"""
|
||||
token = authenticated_client.headers.get("Authorization")
|
||||
url_with_token = f"{websocket_url}?token={token.replace('Bearer ', '')}"
|
||||
|
||||
async with connect(url_with_token) as websocket:
|
||||
yield websocket
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_websocket_connection(self, websocket_url):
|
||||
"""测试WebSocket连接建立"""
|
||||
try:
|
||||
async with connect(websocket_url) as websocket:
|
||||
assert websocket.open
|
||||
except ConnectionRefusedError:
|
||||
pytest.skip("WebSocket服务未启动")
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_websocket_ping_pong(self, websocket_connection):
|
||||
"""测试WebSocket心跳机制"""
|
||||
ping_message = {
|
||||
"type": "ping",
|
||||
"timestamp": 1234567890
|
||||
}
|
||||
|
||||
await websocket_connection.send(json.dumps(ping_message))
|
||||
|
||||
response = await asyncio.wait_for(websocket_connection.recv(), timeout=5.0)
|
||||
pong_message = json.loads(response)
|
||||
|
||||
assert pong_message["type"] == "pong"
|
||||
assert "timestamp" in pong_message
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_websocket_subscribe(self, websocket_connection):
|
||||
"""测试WebSocket订阅"""
|
||||
subscribe_message = {
|
||||
"type": "subscribe",
|
||||
"channel": "notifications"
|
||||
}
|
||||
|
||||
await websocket_connection.send(json.dumps(subscribe_message))
|
||||
|
||||
response = await asyncio.wait_for(websocket_connection.recv(), timeout=5.0)
|
||||
message = json.loads(response)
|
||||
|
||||
assert message["type"] in ["subscribe_ack", "pong"]
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_websocket_multiple_messages(self, websocket_connection):
|
||||
"""测试WebSocket多消息处理"""
|
||||
messages = [
|
||||
{"type": "ping"},
|
||||
{"type": "subscribe", "channel": "test"},
|
||||
{"type": "ping"}
|
||||
]
|
||||
|
||||
responses = []
|
||||
for msg in messages:
|
||||
await websocket_connection.send(json.dumps(msg))
|
||||
try:
|
||||
response = await asyncio.wait_for(websocket_connection.recv(), timeout=2.0)
|
||||
responses.append(json.loads(response))
|
||||
except asyncio.TimeoutError:
|
||||
pass
|
||||
|
||||
assert len(responses) >= 2
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_websocket_invalid_message(self, websocket_connection):
|
||||
"""测试WebSocket无效消息处理"""
|
||||
invalid_messages = [
|
||||
"invalid json",
|
||||
"",
|
||||
json.dumps({"type": "unknown_type"}),
|
||||
json.dumps({})
|
||||
]
|
||||
|
||||
for msg in invalid_messages:
|
||||
try:
|
||||
await websocket_connection.send(msg)
|
||||
await asyncio.sleep(0.5)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_websocket_connection_close(self, websocket_url):
|
||||
"""测试WebSocket连接关闭"""
|
||||
async with connect(websocket_url) as websocket:
|
||||
assert websocket.open
|
||||
await websocket.close()
|
||||
assert not websocket.open
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_websocket_timeout(self, websocket_url):
|
||||
"""测试WebSocket超时"""
|
||||
try:
|
||||
async with connect(websocket_url, ping_timeout=2.0) as websocket:
|
||||
await asyncio.sleep(3.0)
|
||||
except (ConnectionClosed, asyncio.TimeoutError):
|
||||
pass
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_websocket_concurrent_connections(self, websocket_url):
|
||||
"""测试WebSocket并发连接"""
|
||||
async def create_connection():
|
||||
try:
|
||||
async with connect(websocket_url) as websocket:
|
||||
await websocket.send(json.dumps({"type": "ping"}))
|
||||
await asyncio.wait_for(websocket_connection.recv(), timeout=2.0)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
connections = [create_connection() for _ in range(5)]
|
||||
await asyncio.gather(*connections, return_exceptions=True)
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_websocket_large_message(self, websocket_connection):
|
||||
"""测试WebSocket大消息处理"""
|
||||
large_data = "x" * 10000
|
||||
message = {
|
||||
"type": "test",
|
||||
"data": large_data
|
||||
}
|
||||
|
||||
await websocket_connection.send(json.dumps(message))
|
||||
|
||||
try:
|
||||
response = await asyncio.wait_for(websocket_connection.recv(), timeout=5.0)
|
||||
assert response
|
||||
except asyncio.TimeoutError:
|
||||
pass
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_websocket_reconnect(self, websocket_url):
|
||||
"""测试WebSocket重连"""
|
||||
for i in range(3):
|
||||
try:
|
||||
async with connect(websocket_url) as websocket:
|
||||
await websocket.send(json.dumps({"type": "ping"}))
|
||||
response = await asyncio.wait_for(websocket.recv(), timeout=2.0)
|
||||
assert response
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_websocket_unicode_message(self, websocket_connection):
|
||||
"""测试WebSocket Unicode消息"""
|
||||
unicode_message = {
|
||||
"type": "test",
|
||||
"content": "测试中文🎉🚀"
|
||||
}
|
||||
|
||||
await websocket_connection.send(json.dumps(unicode_message))
|
||||
|
||||
try:
|
||||
response = await asyncio.wait_for(websocket_connection.recv(), timeout=2.0)
|
||||
assert response
|
||||
except asyncio.TimeoutError:
|
||||
pass
|
||||
Reference in New Issue
Block a user