前言
在线聊天室的核心诉求是「实时、稳定、安全、易用」------ 实时是聊天体验的核心,稳定是用户持续使用的前提,安全是用户信息与交互的保障,易用则直接影响用户留存。本次测试围绕这四个核心,覆盖功能、接口、兼容性、安全等多个维度,全程模拟真实线上使用场景,确保系统上线后能满足基础聊天交互需求,应对常规使用中的各类情况。
一、测试基础信息
本次在线聊天室系统仅实现用户登录 、发送消息两大核心功能,仅支持普通用户单一身份,所有登录成功的用户可进入聊天室发送消息,保证基础功能的可用性、稳定性与安全性。
1.1 测试背景
本次测试的在线聊天室系统,为轻量化即时通讯工具,仅实现核心基础功能:支持用户账号密码登录校验、登录成功后进入聊天页面、用户可发送文本消息并实时展示在聊天窗口。本次测试主要目的为验证系统在 Edge 浏览器环境下的基础功能稳定性,通过接口测试保证登录、发送消息业务逻辑的正确性,通过 UI 测试保证页面可用性与基础交互流畅性,确保核心功能无逻辑漏洞、无使用障碍。
1.2 测试范围
本次测试覆盖以下模块:
- 用户登录模块
- 消息发送模块
- 登录 / 消息发送接口业务逻辑模块
- 前端页面展示与基础交互模块
- 接口安全性与异常场景测试
二、设计测试用例与分析
测试用例设计方案

在执行测试前,完成对在线聊天室系统的需求拆解与功能分析,从易用性、兼容性、功能、安全性、界面五个维度设计测试用例。设计原则:优先覆盖用户高频操作(登录、发消息),全覆盖正常场景,同时针对异常输入、非法请求、无权限操作等边界场景设计用例,通过 XMind 完成系统需求拆解与测试用例编写。
三、执行测试用例
3.1 UI 自动化测试
(1)需求收集
本次测试的在线聊天室系统,仅支持普通用户登录、登录后发送文本消息两大核心功能,需完成登录校验、消息发送展示、页面基础交互的可用性验证。
(2)页面分析
聊天室系统核心页面:
- 用户登录页面 :127.0.0.1:8080/login.html
支持「账号 + 密码」单一登录方式,登录成功跳转聊天页面,登录失败提示错误信息。 - 聊天页面 :127.0.0.1:8080/client.html
仅登录成功用户可访问,包含消息展示区、消息输入框、发送按钮,输入文本后点击发送可实时展示消息。
(3)设计测试用例
根据页面分析,通过 XMind 完成登录、消息发送、页面跳转、异常输入等场景的测试用例设计。
(4)搭建自动化环境
本次 UI 自动化测试环境:Java + IDEA + Selenium + WebDriverManager + Edge 浏览器
(5)执行测试代码
执行自动化测试代码,完成登录、消息发送、页面校验等核心场景自动化执行。详细代码:https://gitee.com/lu-shengyu-java/chatroom-AutoTest.git
3.2 接口自动化测试
(1)需求分析
对在线聊天室系统进行需求分析,筛选用户登录接口 、发送消息接口两个核心接口,针对接口的参数校验、业务逻辑、安全性进行自动化测试。
(2)接口测试用例设计
针对两个核心接口设计全场景用例:
- 登录接口:正确账号密码、错误密码、空账号、空密码、不存在账号、非法参数等场景;
- 发送消息接口:登录成功后发送正常消息、未登录发送消息、空消息、超长消息、无权限请求等场景。
(3)搭建自动化测试平台
本次接口自动化测试基于 Python 搭建,核心依赖库:
- pytest:调度执行测试用例;
- allure-pytest:生成可视化测试报告;
- requests:处理 HTTP 接口请求;
- PyYAML:解析配置文件与测试数据;
- jsonschema:校验接口返回数据结构。
(4)执行自动化测试代码
执行接口自动化测试代码,完成所有接口场景的自动化验证。详细代码:https://gitee.com/lu-shengyu-java/chatroom-AutoTest.git
(5)生成测试报告
使用 allure-pytest 生成静态测试报告,清晰展示接口通过率、异常场景、断言结果。
四、测试核心代码
4.1 UI 自动化核心代码
(1)用户登录成功测试
模拟用户输入正确账号密码,完成登录并校验跳转结果
//用户登录成功用例
public void loginSuc() throws IOException {
driver.findElement(By.cssSelector("#username")).clear();
driver.findElement(By.cssSelector("#username")).sendKeys("zhangsan");
driver.findElement(By.cssSelector("#password")).clear();
driver.findElement(By.cssSelector("#password")).sendKeys("123");
driver.findElement(By.cssSelector("#submit")).click();
wait.until(ExpectedConditions.alertIsPresent());
Alert alert = driver.switchTo().alert();
alert.accept();
driver.findElement(By.cssSelector("body > div.client-container > div > div.left > div.tab > div.tab-session"));
}
(2)发送消息成功测试
登录后输入消息,发送并校验消息是否展示,登陆至收信人账号,校验发送内容与接收内容是否一致。
public void sendMessageTest() throws IOException {
driver.findElement(By.cssSelector("body > div.client-container > div > div.left > div.tab > div.friend")).click();
driver.findElement(By.cssSelector("#friend-list > li:nth-child(1) > h4")).click();
SEND_MESSAGE = "测试信息"+getRandomNumber(100,999);
driver.findElement(By.cssSelector("body > div.client-container > div > div.right > textarea")).sendKeys(SEND_MESSAGE);
driver.findElement(By.cssSelector("body > div.client-container > div > div.right > div.ctrl > button")).click();
ScreenShot(Thread.currentThread().getStackTrace()[1].getMethodName());
driver.get(host+"/login.html");
driver.findElement(By.cssSelector("#username")).clear();
driver.findElement(By.cssSelector("#username")).sendKeys("lisi");
driver.findElement(By.cssSelector("#password")).clear();
driver.findElement(By.cssSelector("#password")).sendKeys("123");
driver.findElement(By.cssSelector("#submit")).click();
wait.until(ExpectedConditions.alertIsPresent());
Alert alert = driver.switchTo().alert();
alert.accept();
driver.findElement(By.cssSelector("body > div.client-container > div > div.right > div.messages-show ")).click();
driver.findElement(By.cssSelector("#session-list > li")).click();
int num = driver.findElements(By.cssSelector("body > div.client-container > div > div.right > div.messages-show > div")).size();
String sendMessage = driver.findElement(By.cssSelector("body > div.client-container > div > div.right > div.messages-show > div:nth-child("+num+") > div > p")).getText();
ScreenShot(Thread.currentThread().getStackTrace()[1].getMethodName());
assert sendMessage.equals(SEND_MESSAGE);
}
4.2 接口自动化核心代码
(1)登录接口异常场景测试(错误密码 / 空账号)
@pytest.mark.parametrize("case_desc, username, password", [
("密码错误", "zhangsan", "1234"), # 错密码
("用户不存在", "lisii", "123"), # 错用户
("用户名为空", "", "123"), # 用户空
("密码为空", "zhangsan", ""), # 密码空
("用户密码全错", "wangwu", "666"), # 全错
])
def test_login_fail(self, case_desc, username, password):
# 失败响应 schema
fail_schema = {
"$schema": "http://json-schema.org/draft-07/schema#",
"type": "object",
"required": ["userId", "userName"],
"properties": {
"userId": {"type": "integer"},
"userName": {"type": "string"}
}
}
# 构造参数
param = {
"username": username,
"password": password
}
# 发送请求(form表单格式 data=)
r = Request().post(url=self.url, data=param)
resp_json = r.json()
# 1. 校验结构
validate(instance=resp_json, schema=fail_schema)
# 2. 失败断言:必须返回 userId=0,userName=""
assert resp_json["userId"] == 0, f"【{case_desc}】失败预期userId=0"
assert resp_json["userName"] == "", f"【{case_desc}】失败预期用户名为空"
(2)发送消息接口无权限测试(未登录)
# 未登录无法发送消息 → 401无权限
@pytest.mark.asyncio
async def test_websocket_send_fail_no_login(self):
msg = {
"type": "message",
"sessionId": read_yaml("data.yml", "sessionId"),
"content": "未登录测试消息",
"fromId": 1,
"fromName": "zhangsan"
}
try:
# 不携带 Cookie 连接
async with websockets.connect(self.ws_url) as ws:
await ws.send(json.dumps(msg))
# 加超时,防止一直卡死
resp = await asyncio.wait_for(ws.recv(), timeout=1)
except:
assert True
return
assert False
(3)YAML 配置工具类
用于保存登录 token,供后续消息发送接口使用
# yaml文件操作工具类
import os
import yaml
# 写入数据(保存token)
def write_yaml(filename, data):
with open(os.getcwd()+"/data/"+filename, mode="a+", encoding="utf-8") as f:
yaml.safe_dump(data, stream=f)
# 读取数据(获取token)
def read_yaml(filename, key):
with open(os.getcwd()+"/data/"+filename, mode="r", encoding="utf-8") as f:
data = yaml.safe_load(stream=f)
return data[key]
# 清空文件
def clear_yaml(filename):
with open(os.getcwd()+"/data/"+filename, mode="w", encoding="utf-8") as f:
f.truncate()
五、Bug 管理与项目总结
5.1 测试发现与 Bug 汇总
本次测试覆盖登录、发送消息核心功能与接口,发现并记录以下问题,已归类并提供优化建议:
表格
| 模块 | 问题描述 | 缺陷等级 | 改进建议 |
|---|---|---|---|
| 登录模块 | 登录接口未做请求频率限制,可暴力破解密码 | 中 | 后端添加接口限流规则,同一 IP 短时间多次失败锁定账号 |
| 登录模块 | 登录失败提示信息过于笼统,未区分「账号不存在」和「密码错误」 | 低 | 优化接口返回提示,精准告知用户错误原因 |
| 注册模块 | 注册时未对用户账号或密码进行要求 | 中 | 注册时后端对账号与密码进行长度,组成组合进行要求 |
| 界面交互 | 聊天页面无加载状态提示,消息接收无反馈 | 低 | 添加加载动画、接收新信息状态提示,提升用户体验 |
5.2 自动化测试价值分析
本次针对聊天室核心功能实现 UI + 接口自动化覆盖,带来明确价值:
- 效率提升:核心功能回归测试从手动 5 分钟缩短至 15 秒,大幅降低重复测试成本;
- 准确性提升:通过断言替代人工校验,完全避免漏测、误判,保证测试结果可靠;
- 问题前置:自动化用例可快速验证接口逻辑、页面交互问题,在开发阶段提前发现漏洞,降低上线风险;
- 可持续性:后续新增功能可直接复用现有自动化脚本,快速完成回归测试。
5.3 总结与后续规划
总结
本次在线聊天室系统测试围绕「实时、稳定、安全、易用」核心诉求,完成功能、接口、安全、UI 四大维度测试,仅针对已实现的登录、发送消息两大核心功能开展全场景验证。测试过程中,基于 Java 搭建 UI 自动化环境,基于 Python 搭建接口自动化环境,通过 XMind 设计用例,Allure 生成报告,高效发现并推动修复高优先级 Bug,验证了系统基础功能的可用性,同时明确了安全与体验层面的优化方向。
后续规划
- 功能扩展:后续新增消息接收、在线用户展示、消息撤回等功能时,快速补充自动化用例;
- 安全加固:完善接口限流、权限校验、参数过滤等安全机制,提升系统安全性;
- 性能优化:功能完善后使用 JMeter 开展高并发压测,验证多用户同时聊天的稳定性;
- 体验优化:优化页面交互、错误提示、加载状态,提升整体易用性;
- 自动化完善:持续补充异常场景、边界场景自动化用例,实现核心功能 100% 自动化覆盖。