Files
novalon-manage-system/api_integration_tests/tests/test_websocket.py
T
张翔 c50ccd258f feat: 重构测试框架并优化代码结构
refactor(tests): 将e2e_tests迁移到tests_suite和api_integration_tests
style: 为Java类添加文档注释
docs: 更新.gitignore和配置文件
test: 添加性能测试和Playwright测试脚本
chore: 清理旧测试文件和配置
2026-03-14 13:49:39 +08:00

191 lines
6.4 KiB
Python

"""
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