一.报告概述
1、项目背景
Java 聊天室是一款基于 Web 的实时在线聊天系统,主要用于:用户注册登录、好友添加管理、实时消息收发、聊天会话管理、消息历史记录查询。
系统包含以下核心模块:
-
- 用户管理:注册、登录、会话管理
-
- 好友管理:好友搜索、添加、列表管理
-
- 消息会话管理:会话创建、会话列表、最后消息显示
-
- 消息管理:实时消息发送、消息历史记录查询
-
- WebSocket 通信:实时连接建立、消息推送、连接状态管理
2、测试环境
- 操作系统:Windows 11 / Windows 10
- 浏览器:Chrome、Edge
- 测试工具:Selenium、JMeter、postman
二.测试用例

三.手动测试
1.注册功能测试
测试场景一:输入密码:123,但不输入用户名,点击注册
预期结果:弹窗显示 "您输入的用户名/密码为空"


测试场景二:输入未注册过的用户名:咕咕 ,但不设置密码,点击注册
预期结果:弹窗显示 "您输入的用户名/密码为空"


测试场景三:输入已经注册过的用户名"zhangsan"和密码"123",并点击注册
预期结果:弹窗显示"注册失败!用户已存在"


测试场景四:输入未注册过的用户名"咕咕"和密码"123",点击注册
预期结果:弹窗显示 "注册成功",点击确定后跳转到登录页面



2.登录功能测试
测试场景一:输入注册过的用户名"zhangsan"和密码"123"
预期结果:弹窗显示"登陆成功",点击确定后跳转到会话界面



测试场景二:输入错误的/未注册过的用户名和密码
预期结果:弹窗显示"登陆失败"


测试场景三:只输入用户名:"zhangsan",未输入密码
预期结果:弹窗提示"当前输入的用户名/密码为空"


测试场景四:输入密码"123"但不输入用户名
预期结果:弹窗显示"当前输入的用户名/密码为空"


3.搜索好友功能测试
测试场景一:登陆成功之后,在搜索框输入完整的存在的用户名"咕咕"并搜索
预期结果:搜索结果显示该用户



测试场景二:登录成功之后,在搜索框输入完整的不存在的用户名"123"
预期结果:搜索结果显示未查找到匹配的用户



测试场景三:登录成功之后,输入部分存在的用户名称:"咕"
预期结果:搜索结果展示包含搜索框中字段的用户



测试场景四:用户"zhangsan"登陆成功后,搜索框输入用户自己的用户名"zhangsan"
预期结果:搜索结果显示未找到匹配的用户



测试场景五:搜索到的好友添加过
预期结果:显示该好友,添加按钮变为聊天,点击后跳转到与该好友的聊天界面


4.添加好友功能测试
测试场景:搜索到用户之后,点击对应的添加按钮
预期结果:弹窗显示添加好友成功,添加按钮变为聊天按钮,点击好友列表显示该好友




5.发送消息功能测试
测试场景:在和"1"的聊天界面的聊天框输入"你好",并点击"发送"按钮
预期结果:聊天界面显示由本人"zhangsan"发出消息"你好"


6.接收消息功能测试
测试场景:在"zhangsan"向"1"发送了"你好"之后,登录"1"的账号
预期结果:显示"zhangsan"向自己发来的"你好"




7.会话管理功能测试
测试场景一:点击好友列表"咕咕"
预期结果:跳转到与"咕咕"的聊天界面,并新增会话记录



测试场景二:点击会话列表最下面的"lisi"
预期结果:在好友列表点击"lisi",与"lisi"的会话记录置顶并高亮显示



四.自动化测试

Utils工具类
package com.example.common;
import io.github.bonigarcia.wdm.WebDriverManager;
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.Alert;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.TakesScreenshot;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.time.Duration;
//工具类,实现浏览器打开,关闭,截图
public class Utils {
public static WebDriver driver=null;
public static WebDriverWait wait=null;
public static String detailSrl=null;
//构造方法
public Utils(String url){
WebDriver driver = createDriver();
driver.get(url);
//显示等待
wait = new WebDriverWait(driver, Duration.ofSeconds(10));
}
//创建Driver对象
public static WebDriver createDriver(){
if(driver==null){
//下载驱动
WebDriverManager.chromedriver().setup();
//驱动配置
ChromeOptions options=new ChromeOptions();
options.addArguments("--remote-allow-origins=*");
//创建driver对象
driver=new ChromeDriver(options);
//添加隐式等待
driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(3));
}
return driver;
}
//截图
public void screenShot(String funcName) throws IOException {
WebDriver driver = createDriver();
SimpleDateFormat format1=new SimpleDateFormat(("yyyy-MM-dd"));
SimpleDateFormat format2=new SimpleDateFormat("HH_mm_ss");
String dirTime=format1.format(System.currentTimeMillis());
String fileTime=format2.format(System.currentTimeMillis());
String fileName="./src/test/java/com/example/img/"+dirTime+"/"+funcName+"_"+fileTime+".png";
File srcFile = ((TakesScreenshot) driver).getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(srcFile,new File(fileName));
}
//关闭浏览器
public void exit(){
driver.quit();
}
//处理弹窗
//隐式等待不等弹窗,因此需要显式等待弹窗操作
//否则报错NoAlertPresentException
public static void alert(){
wait.until(ExpectedConditions.alertIsPresent());
Alert alert=driver.switchTo().alert();
alert.accept();
}
}
RunTest 运行主类
package com.example.cases;
import java.io.IOException;
public class RunTest {
public static void main(String[] args) throws InterruptedException, IOException {
TestRegister register=new TestRegister();
//检查注册页面
register.checkRegisterRight();
//注册用户名/密码为空
Thread.sleep(2000);
register.registerFailNull();
//输入注册过的用户名和密码
Thread.sleep(2000);
register.registeredFail();
//注册成功
Thread.sleep(2000);
register.registerSuc();
TestLogin login=new TestLogin();
//检查登陆页面
login.checkLoginRight();
//用户名/密码为空
login.loginFailNull();
//用户名错误
login.loginFailErrorName();
//密码错误
login.loginFailErrorPassword();
//登陆成功
login.loginSuc();
TestClient testClient=new TestClient();
//检查是否正常打开
testClient.checkClientRight();
//验证发送消息功能
testClient.Client();
//搜索好友失败
testClient.searchFriendFail();
//添加好友成功
testClient.addFriendSuc();
login.exit();
}
}
TestLogin 登陆测试类
package com.example.cases;
import com.example.common.Utils;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import java.io.IOException;
public class TestLogin extends Utils {
public static String src="http://49.234.179.251:8081/login.html";
public TestLogin(){
super(src);
}
/**
* 检查登陆页面是否正常打开
*/
public void checkLoginRight() throws IOException {
//截图
screenShot(Thread.currentThread().getStackTrace()[1].getMethodName());
//检查输入框,登录,注册按钮是否存在
driver.findElement(By.cssSelector("#username"));
driver.findElement(By.cssSelector("#password"));
driver.findElement(By.cssSelector("#submit"));
driver.findElement(By.cssSelector("#register"));
}
/**
* 输入正确的用户名和密码,登陆成功
*/
public void loginSuc() throws InterruptedException, IOException {
//找到用户名输入框清空
driver.findElement(By.cssSelector("#username")).clear();
//找到密码输入框清空
driver.findElement(By.cssSelector("#password")).clear();
//找到用户名输入框输入正确的账号
driver.findElement(By.cssSelector("#username")).sendKeys("zhangsan");
//找到密码输入框输入正确的密码
driver.findElement(By.cssSelector("#password")).sendKeys("123");
driver .findElement(By.cssSelector("#submit")).click();
Thread.sleep(1000);
alert();
//通过是否存在该元素判断是否登陆成功
driver.findElement(By.cssSelector("body > div.client-container > div > div.left > div.search > button"));
}
/**
* 登陆失败
* 用户名和密码都为空
*/
public void loginFailNull() throws IOException {
//在登陆成功后测试该功能,因此需要回退,并清空输入框内容
//driver.navigate().back();//但如果先执行登录失败就不需要回退
//找到用户名输入框清空
driver.findElement(By.cssSelector("#username")).clear();
//找到密码输入框清空
driver.findElement(By.cssSelector("#password")).clear();
//点击提交按钮
driver.findElement(By.cssSelector("#submit")).click();
alert();
}
/**
* 输入正确的密码,错误的用户名,登陆失败
*/
public void loginFailErrorName() throws IOException {
driver.findElement(By.cssSelector("#username")).clear();
//找到密码输入框清空
driver.findElement(By.cssSelector("#password")).clear();
//找到用户名输入框输入正确的账号
driver.findElement(By.cssSelector("#username")).sendKeys("z");
//找到密码输入框输入正确的密码
driver.findElement(By.cssSelector("#password")).sendKeys("123");
driver .findElement(By.cssSelector("#submit")).click();
alert();
}
/**
* 输入正确的密码,错误的密码,登陆失败
*/
public void loginFailErrorPassword() throws IOException {
driver.findElement(By.cssSelector("#username")).clear();
//找到密码输入框清空
driver.findElement(By.cssSelector("#password")).clear();
//找到用户名输入框输入正确的账号
driver.findElement(By.cssSelector("#username")).sendKeys("zhangsan");
//找到密码输入框输入正确的密码
driver.findElement(By.cssSelector("#password")).sendKeys("1");
driver .findElement(By.cssSelector("#submit")).click();
alert();
}
}
TestRegister 注册测试类
package com.example.cases;
import com.example.common.Utils;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.support.ui.ExpectedConditions;
import java.io.IOException;
public class TestRegister extends Utils {
public static String src="http://49.234.179.251:8081/register.html";
public TestRegister() {
super(src);
}
/**
* 检查页面是否正常打开
*/
public void checkRegisterRight() throws IOException {
//截图
screenShot(Thread.currentThread().getStackTrace()[1].getMethodName());
driver.findElement(By.cssSelector("#username"));
driver.findElement(By.cssSelector("#password"));
driver.findElement(By.cssSelector("#submit"));
}
/**
* 输入的用户名,密码为空
*/
public void registerFailNull(){
driver.findElement(By.cssSelector("#username")).clear();
driver.findElement(By.cssSelector("#password")).clear();
driver.findElement(By.cssSelector("#submit")).click();
alert();
}
/**
* 输入用户名和密码,注册成功
*/
public void registerSuc(){
driver.findElement(By.cssSelector("#register")).click();
driver.findElement(By.cssSelector("#username")).clear();
driver.findElement(By.cssSelector("#password")).clear();
driver.findElement(By.cssSelector("#username")).sendKeys("1234");
driver.findElement(By.cssSelector("#password")).sendKeys("1234");
driver.findElement(By.cssSelector("#submit")).click();
alert();
}
/**
* 输入注册过的用户名和密码
*/
public void registeredFail(){
driver.findElement(By.cssSelector("#username")).clear();
driver.findElement(By.cssSelector("#password")).clear();
driver.findElement(By.cssSelector("#username")).sendKeys("zhangsan");
driver.findElement(By.cssSelector("#password")).sendKeys("123");
driver.findElement(By.cssSelector("#submit")).click();
alert();
}
}
TestClient 会话测试类
package com.example.cases;
import com.example.common.Utils;
import org.openqa.selenium.By;
import java.io.IOException;
public class TestClient extends Utils {
public static String src="http://49.234.179.251:8081/client.html";
public TestClient() {
super(src);
}
//检查正常打开
public void checkClientRight() throws IOException {
screenShot(Thread.currentThread().getStackTrace()[1].getMethodName());
//通过是否存在该元素判断是否登陆成功
driver.findElement(By.cssSelector("body > div.client-container > div > div.left > div.search > button"));
}
//点击查看"lisi"聊天记录,并且向"lisi"发送"你好"
public void Client() throws IOException {
driver.findElement(By.cssSelector("#session-list > li:nth-child(4)")).click();
screenShot(Thread.currentThread().getStackTrace()[1].getMethodName());
driver.findElement(By.cssSelector("body > div.client-container > div > div.right > textarea")).sendKeys("你好");
driver.findElement(By.cssSelector("body > div.client-container > div > div.right > div.ctrl > button")).click();
screenShot(Thread.currentThread().getStackTrace()[1].getMethodName());
}
//添加好友"1234"成功
public void addFriendSuc(){
driver.findElement(By.cssSelector("body > div.client-container > div > div.left > div.search > input[type=text]"))
.clear();
driver.findElement(By.cssSelector("body > div.client-container > div > div.left > div.search > input[type=text]"))
.sendKeys("1234");
driver.findElement(By.cssSelector("body > div.client-container > div > div.left > div.search > button")).click();
driver.findElement(By.cssSelector("body > div.client-container > div > div.right > div.message-show > div:nth-child(1) > div.add-friend > button")).click();
alert();
}
//搜索好友失败
public void searchFriendFail() throws InterruptedException {
driver.findElement(By.cssSelector("body > div.client-container > div > div.left > div.search > input[type=text]"))
.sendKeys("aaa");
driver.findElement(By.cssSelector("body > div.client-container > div > div.left > div.search > button")).click();
// 添加等待时间,确保搜索结果能够显示
Thread.sleep(2000);
String text = driver.findElement(By.xpath("/html/body/div[2]/div/div[2]/div[2]/div")).getText();
System.out.println(text);
assert text.equals("未找到匹配的用户");
}
}
五.性能测试
1.单一接口测试
登录接口




获取用户信息




获取好友列表




获取历史会话消息




获取会话列表消息




查询好友




2.聚合报告

3、TPS可视化
Transactions per Second(TPS)监听器是⼀个用于分析系统吞吐量的重要工具。TPS,即每秒事务数,表示一个客户机向服务器发送请求后服务器做出反应的过程。这个指标反映了系统在同一时间内处理业务的最大能力。TPS值越高,说明系统的处理能力越强。

4、响应时间可视化
Response Times Over Time主要用于监听整个事务运行期间的响应时间。在测试过程中,可以通过观察并分析响应时间的实时平均值以及整体响应时间的走向。

5、活跃线程数可视化
Active Threads Over Time 监听器显示测试执行期间并发用户(线程)数量的实时变化,以折线图形式展示活跃线程数随时间变化的趋势帮助识别负载模式、峰值和低谷。

6.测试报告






