首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >论坛系统测试报告

论坛系统测试报告

作者头像
趙卋傑
发布2026-01-12 14:43:35
发布2026-01-12 14:43:35
550
举报

1.项目背景

这是一个基于Spring+前后端分离的论坛系统项目

本项目是一款集用户管理、帖子互动、站内通信于一体的论坛类应用,由本人独立完成设计、开发、测试及云服务器部署的全流程工作

1.1 项目简介

模块设计

  • 用户模块:实现用户登录、注册及个人信息维护功能,保障用户身份管理与信息安全。
  • 帖子模块:支持帖子发布、管理、列表展示及点赞互动,满足用户内容创作与互动需求。
  • 帖子回复功能:实现针对帖子的评论与互动回复,强化社区交流属性。
  • 站内信功能:支持向指定用户发送消息,采用长轮询技术实现实时消息推送,提升用户沟通效率。

模拟服务器有效地将消息推送到客户端(或浏览器)

技术栈

  • 后端:基于 Spring Boot + Spring MVC 构建服务端逻辑,以 MySQL 作为数据存储引擎,保障系统稳定性与数据可靠性。
  • 前端:通过 Bootstrap 实现响应式页面布局,结合 jQuery 完成 DOM 操作与 AJAX 异步请求,确保前端交互体验流畅直观。

1.2 应用技术

  • 后端:Spring,Spring Boot,Spring MVC,MyBatis
  • 数据库:MySQL
  • 前端:HTML,CSS,JavaScript,Bootstrap,jQuery3
  • 采用统一返回格式 + 全局错误信息定义,实现前后端交互结果的标准化、一致性处理,提升接口可读性与稳定性
  • 通过 @ControllerAdvice + @ExceptionHandler 注解组合,构建全局异常处理机制,统一拦截、规范化异常响应
  • 利用拦截器技术实现用户登录状态校验,精准拦截未授权请求,强化系统权限管理与操作安全性
  • 借助MybatisGeneratorConfig 工具自动生成常规增删改查方法,大幅提升数据层开发效率,降低重复编码成本
  • 集成Swagger实现自动生成API测试接⼝
  • 针对数据库高频查询字段建立索引,并通过查询计划工具分析索引生效情况,显著优化数据查询性能与系统响应速度

2.项目模块及实现功能

  1. 注册
  2. 登陆模块
  3. 板块模块
  1. 文章模块
  1. 回复模块
  1. 站内信模块

2.测试用例

测试用例pdf

https://zbzt2ybw2o.feishu.cn/docx/ZILCdHsI2oqLjqxcci1cAGcznff#share-MVdCdEinJoqqy8xeICDchuBUnwd

3.自动化测试

3.1 公共类 Utils

  1. 创建驱动createDriver()
  2. 构造函数(页面初始化)Utils(String url)
  3. 屏幕截图getScreenShot(String str)
  4. 登录封装login()
  5. 滑动页面slidePage(String selector)
代码语言:javascript
复制
package common;

import io.github.bonigarcia.wdm.WebDriverManager;
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.time.Duration;

public class Utils {
    public static WebDriver driver;
    public static WebDriver createDriver(){
        if(driver == null){
            WebDriverManager.chromedriver().setup();
            ChromeOptions options = new ChromeOptions();
            //允许访问所有链接
            options.addArguments("--remote-allow-origins=*");
            driver = new ChromeDriver(options);
            //等待
            driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(3));
        }
        return driver;
    }
    public Utils(String url) {
        //调用driver对象
        driver = createDriver();
        //访问url
        driver.get(url);
        //窗口最大化
        driver.manage().window().maximize();
    }

    //屏幕截图
    public void getScreenShot(String str) throws IOException {

        //屏幕截图  时间戳
        SimpleDateFormat sim1 = new SimpleDateFormat("yyyy-MM-dd");
        SimpleDateFormat sim2 = new SimpleDateFormat("HHmmssSS");

        String dirTime = sim1.format(System.currentTimeMillis());
        String fileTime = sim2.format(System.currentTimeMillis());

        //根据上面的时间设置 保存图片的文件名字
        String filename = "./src/test/image/" + dirTime + "/" + str +"-" +fileTime + ".png";
        File srcFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
        //复制放到指定位置
        FileUtils.copyFile(srcFile,new File(filename));
    }
    public static void login(){
        //输入用户名
        driver.findElement(By.cssSelector("#username")).click();
        driver.findElement(By.cssSelector("#username")).sendKeys("xiaoshuai");
        //输入密码
        driver.findElement(By.cssSelector("#password")).click();
        driver.findElement(By.cssSelector("#password")).sendKeys("123456");
        //点击登录按钮
        driver.findElement(By.cssSelector("#submit")).click();
        //检查点击登录是否成功
        //通过查看logo是否登录成功
        driver.findElement(By.cssSelector("body > div.page > header.navbar.navbar-expand-md.navbar-light.d-print-none > div > h1 > a > img"));
        //通过查看发布帖子是否登录成功
        driver.findElement(By.cssSelector("#\\34 04Lounge-content > div.page-header.d-print-none > div > div > div.col-auto.ms-auto.d-print-none > div > a.btn.btn-primary.d-none.d-sm-inline-block.article_post"));
        //返回登录页面
        // driver.navigate().back();
        //刷新页面
        // driver.navigate().refresh();
    }

    //滑动页面
    public static WebElement slidePage(String selector) throws InterruptedException {
        JavascriptExecutor js = (JavascriptExecutor) driver;
        WebElement target = driver.findElement(By.cssSelector(selector));
        js.executeScript("arguments[0].scrollIntoView({behavior: 'smooth', block: 'center'});", target);
        //等待页面已经划至发布按钮处
        Thread.sleep(500);

        return target;
    }
}

3.2 注册界面 RegisterPageTest

  1. RegisterPageRight(): 测试注册界面是否正常显示
  2. RegisterFail():测试注册失败(用户已存在,密码和确认密码不一致)
  3. RegisterSuc(): 测试注册成功
代码语言:javascript
复制
package test;

import common.Utils;
import org.openqa.selenium.By;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.io.IOException;
import java.time.Duration;

/**
 * 注册界面测试
 */
public class RegisterPageTest extends Utils {
    public static String url = "http://62.234.142.221:58080/sign-in.html";
    public RegisterPageTest() {
        super(url);
    }

    /**
     * 检查页面是否可以正常打开
     */
    public void RegisterPageRight() {
        //论坛logo图标
        driver.findElement(By.cssSelector("body > div > div > div > div:nth-child(1) > div > div.text-center.mb-4 > img"));
        //检查点击注册按钮
        //body > div > div > div > div:nth-child(1) > div > div.text-center.text-muted.mt-3 > a
        driver.findElement(By.cssSelector("body > div > div > div > div:nth-child(1) > div > div.text-center.text-muted.mt-3 > a"));
        System.out.println("页面正常打开");
    }

    //注册失败01--该用户已存在
    public void RegisterFai01() throws IOException, InterruptedException {
        //在登录页面点击注册按钮
        driver.findElement(By.cssSelector("body > div > div > div > div:nth-child(1) > div > div.text-center.text-muted.mt-3 > a")).click();
        //输入用户名
        driver.findElement(By.cssSelector("#username")).sendKeys("测试username");
        //输入昵称
        driver.findElement(By.cssSelector("#nickname")).sendKeys("测试nickname");
        //输入密码
        driver.findElement(By.cssSelector("#password")).sendKeys("123");
        //输入确认密码
        driver.findElement(By.cssSelector("#passwordRepeat")).sendKeys("123");
        //点击同意使用条款和隐私服务
        driver.findElement(By.cssSelector("#policy")).click();
        //点击注册
        driver.findElement(By.cssSelector("#submit")).click();
        //获取异常文本
        String fail01 = driver.findElement(By.cssSelector("body > div.jq-toast-wrap.bottom-right > div > h2")).getText();
        Thread.sleep(500);
        //截图
        getScreenShot(getClass().getName());
        System.out.println(fail01);
        assert fail01.equals("警告");

    }
    //密码和确认密码不一致
    public void RegisterFail02 () throws IOException, InterruptedException {
        //刷新一下页面
        driver.navigate().refresh();
        //输入用户名
        driver.findElement(By.cssSelector("#username")).sendKeys("zhao");
        //输入昵称
        driver.findElement(By.cssSelector("#nickname")).sendKeys("30");
        //密码
        driver.findElement(By.cssSelector("#password")).sendKeys("123456");
        //确认密码
        driver.findElement(By.cssSelector("#passwordRepeat")).sendKeys("123");
        //点击同意隐私
        driver.findElement(By.cssSelector("#policy")).click();
        //点击注册
        driver.findElement(By.cssSelector("#submit")).click();
        //获取当前异常文本
        String fail02 = driver.findElement(By.cssSelector("#signUpForm > div > div:nth-child(5) > div > div")).getText();
        Thread.sleep(500);
        //屏幕截图
        getScreenShot(getClass().getName());
        //断言
        assert fail02.equals("请检查确认密码");
    }
    /**
     * 注册成功
     */
    public void RegisterSuc() throws IOException, InterruptedException {

        //刷新页面, 清空输入框
        driver.navigate().refresh();

        driver.findElement(By.cssSelector("#username")).sendKeys("testName");
        driver.findElement(By.cssSelector("#nickname")).sendKeys("testNickname");
        driver.findElement(By.cssSelector("#password")).sendKeys("123456");
        driver.findElement(By.cssSelector("#passwordRepeat")).sendKeys("123456");
        driver.findElement(By.cssSelector("#policy")).click();

        driver.findElement(By.cssSelector("#submit")).click();

        //点击注册后进入登录界面

        //截图
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(3)); //显示等待
        wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("body > div > div > div > div:nth-child(1) > div > div.card.card-md > div > h2")));

        getScreenShot(getClass().getName());
        //获取当前页面url
        String ele = driver.getCurrentUrl();
        //如果已经跳转至登录界面, 则注册成功
        assert ele.equals("http://62.234.142.221:58080/sign-in.html");

    }
}

3.3 登陆界面 LoginPage

  1. loginPageRight():测试页面是否正常显示
  2. loginSuc():测试登录功能---成功登录
  3. loginFail():测试登录功能---登录失败,以用户名存在,密码错误和用户名不存在,密码非空作为测试用例
代码语言:javascript
复制
package test;

import common.Utils;
import org.openqa.selenium.By;

import java.io.IOException;

public class LoginPageTest extends Utils {

    private static final String url = "http://62.234.142.221:58080/sign-in.html";

    public LoginPageTest() {
        super(url);
    }

    /**
     * 检查页面是否可以正常打开
     */
    public void RegisterPageRight() {
        //论坛logo图标
        driver.findElement(By.cssSelector("body > div > div > div > div:nth-child(1) > div > div.text-center.mb-4 > img"));
        //检查点击注册按钮
        driver.findElement(By.cssSelector("body > div > div > div > div:nth-child(1) > div > div.text-center.text-muted.mt-3 > a"));
        System.out.println("页面正常打开");
    }

    //检查登录功能   成功登录
    public static void LoginSuc(){
        //输入用户名
        driver.findElement(By.cssSelector("#username")).click();
        driver.findElement(By.cssSelector("#username")).sendKeys("xiaoshuai");
        //输入密码
        driver.findElement(By.cssSelector("#password")).click();
        driver.findElement(By.cssSelector("#password")).sendKeys("123456");
        //点击登录按钮
        driver.findElement(By.cssSelector("#submit")).click();
        //检查点击登录是否成功
        //通过查看logo是否登录成功
        driver.findElement(By.cssSelector("body > div.page > header.navbar.navbar-expand-md.navbar-light.d-print-none > div > h1 > a > img"));
        //通过查看发布帖子是否登录成功
        driver.findElement(By.cssSelector("#\\34 04Lounge-content > div.page-header.d-print-none > div > div > div.col-auto.ms-auto.d-print-none > div > a.btn.btn-primary.d-none.d-sm-inline-block.article_post"));

        //返回登录页面
        // driver.navigate().back();
        //刷新页面
        // driver.navigate().refresh();
    }

    //检查登录失败01--密码错误
    public void loginFail01() throws IOException, InterruptedException {
        //输入用户名
        driver.findElement(By.cssSelector("#username")).sendKeys("myp");
        //输入密码
        driver.findElement(By.cssSelector("#password")).sendKeys("123456");
        //点击登录按钮
        driver.findElement(By.cssSelector("#submit")).click();
        //获取当前异常文本
        String fail01 = driver.findElement(By.cssSelector("body > div.jq-toast-wrap.bottom-right > div > h2")).getText();
        //截图
        Thread.sleep(500);
        getScreenShot(getClass().getName());
        assert fail01.equals("警告");

    }

    //用户名为空
    public void loginFail02() throws IOException {
        //刷新一下
        driver.navigate().refresh();
        //用户名
        driver.findElement(By.cssSelector("#username"));
        //输入密码
        driver.findElement(By.cssSelector("#password")).sendKeys("111111");
        //点击登录按钮
        driver.findElement(By.cssSelector("#submit")).click();
        //获取异常文本
        String fail02 = driver.findElement(By.cssSelector("#signInForm > div.mb-3 > div")).getText();
        //截图
        getScreenShot(getClass().getName());
        assert fail02.equals("用户名不能为空");
    }

    //密码为空
    public void loginFail03() throws IOException {
        //刷新
        driver.navigate().refresh();
        //输入用户名
        driver.findElement(By.cssSelector("#username")).sendKeys("myp");
        //密码
        driver.findElement(By.cssSelector("#password"));
        //点击登录按钮
        driver.findElement(By.cssSelector("#submit")).click();
        //获取当前异常文本
        String fail03 = driver.findElement(By.cssSelector("#signInForm > div.mb-2 > div > div")).getText();
        //截图
        getScreenShot(getClass().getName());
        assert fail03.equals("密码不能为空");

    }
}

3.4 论坛首页 HomePage

  1. HomePageFail():测试未登录状态下进入论坛首页
  2. HomePageSuc():测试登录后正常进入论坛首页
代码语言:javascript
复制
package test;

import common.Utils;
import org.openqa.selenium.By;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.io.IOException;
import java.time.Duration;

/**
 * 论坛首页测试
 */
public class HomePage extends Utils {
    private static final String url = "http://62.234.142.221:58080/index.html";
    private static final String LOGIN_URL = "http://62.234.142.221:58080/sign-in.html";

    public HomePage() {
        super(url);
    }

    /**
     * 未登录状态下, 进入论坛首页
     */
    public void HomePageFail() throws IOException, InterruptedException {
        // 直接访问首页
        driver.get(url);
        System.out.println(url);
        // 等待页面跳转完成(处理延迟,避免获取到跳转前的URL)
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(5));
        wait.until(ExpectedConditions.urlContains("sign-in.html"));

        // 获取当前URL
        String curUrl = driver.getCurrentUrl();
        System.out.println(curUrl);

        // 正确断言:当前URL应等于登录页URL,验证跳转成功
        assert curUrl.equals(LOGIN_URL) : "未登录访问首页未正确跳转至登录页,当前URL:" + curUrl;
        System.out.println("未登录访问首页成功跳转至登录页,测试通过");
    }

    /**
     * 登录后, 可以正常进入论坛首页
     */
    public void HomePageSuc() throws IOException, InterruptedException {
        //登陆操作
        Utils.login();

        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(3)); //显示等待
        wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("#article_list_board_title")));

        //检查Java板块是否存在
        driver.findElement(By.cssSelector("#topBoardList > li:nth-child(2) > a > span.nav-link-title"));
        //检查发布帖子按钮
        driver.findElement(By.cssSelector("#\\34 04Lounge-content > div.page-header.d-print-none > div > div > div.col-auto.ms-auto.d-print-none > div > a.btn.btn-primary.d-none.d-sm-inline-block.article_post > svg"));
        //查看首页
        driver.findElement(By.cssSelector("#article_list_board_title"));

        //截图
        getScreenShot(getClass().getName());

    }

}

3.5 发帖界面 PublishPage

  1. publishPostPage():测试正常进入发帖界面
  2. publishPostSuc():测试正常发布帖子功能
  3. publishPostFail():测试发帖失败
代码语言:javascript
复制
package test;

import common.Utils;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.io.IOException;
import java.time.Duration;

/**
 * 发帖界面的相关测试方法
 */
public class PublishPage extends Utils {
    public static String url = "http://62.234.142.221:58080/sign-in.html";
    public PublishPage() {
        super(url);
    }

    /**
     * 测试正常进入发布帖子界面
     */
    public void publishPostPage() throws InterruptedException {
        //登录到论坛首页
        Utils.login();
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(3));
        wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#\\34 04Lounge-content > div.page-header.d-print-none > div > div > div.col-auto.ms-auto.d-print-none > div > a.btn.btn-primary.d-none.d-sm-inline-block.article_post")));

        driver.findElement(By.cssSelector("#\\34 04Lounge-content > div.page-header.d-print-none > div > div > div.col-auto.ms-auto.d-print-none > div > a.btn.btn-primary.d-none.d-sm-inline-block.article_post")).click();
        Thread.sleep(1000);

        //进入页面后查找元素
        wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("#\\34 04Lounge-content > div.page-header.d-print-none > div > div > div > h2")));
        //发新帖
        driver.findElement(By.cssSelector("#\\34 04Lounge-content > div.page-header.d-print-none > div > div > div > h2"));
        //发布按钮
        driver.findElement(By.cssSelector("#article_post_submit"));
    }

    /**
     * 测试正常发布帖子功能
     */
    public void publishPostSuc() throws InterruptedException {
        //点击板块下拉选择板块
        driver.findElement(By.cssSelector("#article_post_borad"));
        //点击招聘信息
        driver.findElement(By.cssSelector("#article_post_borad > option:nth-child(7)")).click();
        //点击标题, 输入内容
        driver.findElement(By.cssSelector("#article_post_title")).click();
        driver.findElement(By.cssSelector("#article_post_title")).sendKeys("测试标题001");
        Thread.sleep(2000);
        //点击内容框,输入内容
        //模拟输入内容
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(3)); //显示等待
        //等待内容输入框加载完成
        wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("#edit-article > div.editormd-toolbar > div > ul > li:nth-child(12) > a > i")));

        WebElement element = driver.findElement(By.cssSelector("#edit-article > div.editormd-toolbar > div > ul > li:nth-child(12) > a > i"));
//        element.sendKeys("测试内容");
        element.click();

        //将页面划至 发布 按钮处
        JavascriptExecutor js = (JavascriptExecutor) driver;
        WebElement publishButton = driver.findElement(By.xpath("//*[@id=\"article_post_submit\"]"));
        js.executeScript("arguments[0].scrollIntoView({behavior: 'smooth', block: 'center'});", publishButton);
        //等待页面已经划至发布按钮处
        Thread.sleep(1000);
        publishButton.click();

    }

    /**
     * 测试发布帖子失败
     */
    public void publishPostFail() throws InterruptedException, IOException {
        //找到发布帖子的按钮
        WebElement element = driver.findElement(By.cssSelector("#\\34 04Lounge-content > div.page-header.d-print-none > div > div > div.col-auto.ms-auto.d-print-none > div > a.btn.btn-primary.d-none.d-sm-inline-block.article_post"));
        element.click();
        //以内容为空作为测试用例
        driver.findElement(By.cssSelector("#article_post_title")).sendKeys("标题");

        //将页面划至 发布 按钮处
        JavascriptExecutor js = (JavascriptExecutor) driver;
        WebElement publishButton = driver.findElement(By.xpath("//*[@id=\"article_post_submit\"]"));
        js.executeScript("arguments[0].scrollIntoView({behavior: 'smooth', block: 'center'});", publishButton);
        //等待页面已经划至发布按钮处
        Thread.sleep(1000);
        publishButton.click();

        //当前还在发帖界面则发帖失败
        driver.findElement(By.cssSelector("#\\34 04Lounge-content > div.page-header.d-print-none > div > div > div > h2"));
        Thread.sleep(1000);
        getScreenShot(getClass().getName());
    }
}

3.6 帖子详情 DetailsPage

  1. DetailsPageRight():测试帖子详情页正常显示
  2. thumbsUp():测试成功点赞
  3. replyPost():测试成功回复帖子
  4. editPageRight():测试编辑帖子页面是否能够正常显示
  5. editSuc():测试成功编辑并发布帖子
代码语言:javascript
复制
package test;

import common.Utils;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.io.IOException;
import java.time.Duration;

/**
 * 测试帖子详情页的相关功能
 */
public class DetailsPage extends Utils {


    public static String url = "http://62.234.142.221:58080/sign-in.html";

    public DetailsPage() {
        super(url);
    }
    /**
     * 测试帖子详情页正常显示
     */
    public void DetailsPageRight() throws InterruptedException {
        Utils.login();
        //将页面滑动至目标元素处  灌水
        WebElement targetPost = Utils.slidePage("#artical-items-body > div:nth-child(10) > div > div.col > div.text-truncate > a > strong");
        targetPost.click();
        //检查详情页面是否有元素  向上滑动
        Utils.slidePage("#details_article_title");

    }

    /**
     * 测试点赞
     */
    public void thumbsUp() throws IOException {

        driver.findElement(By.cssSelector("#details_btn_like_count")).click();
        getScreenShot(getClass().getName());
    }

    /**
     * 测试回复帖子
     */
    public void replyPost() throws InterruptedException, IOException {
        WebElement target = Utils.slidePage("#article_details_reply > div.editormd-toolbar > div > ul > li:nth-child(12) > a");
        target.click();
        //页面滑动至回复按钮
        target = Utils.slidePage("#details_btn_article_reply");
        //点击回复
        target.click();
        getScreenShot(getClass().getName());
    }
    /**
     * 测试编辑帖子页面是否能够正常显示
     */

    public void editPageRight() throws InterruptedException {
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(3)); //显示等待
        //将页面滑动至编辑按钮处
        WebElement target = Utils.slidePage("#details_artile_edit");
        //点击编辑进入博客编辑页
        wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#details_artile_edit")));
        driver.findElement(By.cssSelector("#details_artile_edit")).click();
    }

    /**
     * 测试成功编辑并发布帖子
     */
    public void editSuc() throws InterruptedException {
        WebElement title = driver.findElement(By.cssSelector("#edit_article_title"));
        title.clear();
        //修改标题
        title.sendKeys("666");

        //将页面滑动至提交按钮处
        WebElement target = Utils.slidePage("#edit_article_submit");
        target.click();

        //点击提交后回到论坛首页
        driver.findElement(By.cssSelector("#article_list_board_title"));

    }
}

3.7 站内信 MessagePage

  1. postMessageRight():测试发送站内信界面是否正常显示
  2. postMessageSuc():测试成功发送站内信
  3. messageListRight():测试站内信列表界面正常显示
  4. replyMessage():测试成功回复站内信
代码语言:javascript
复制
package test;

import common.Utils;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.io.IOException;
import java.time.Duration;

/**
 * 测试站内信相关功能
 */
public class MessagePage extends Utils {
    public static String url = "http://62.234.142.221:58080/sign-in.html";
    public MessagePage() {
        super(url);
    }

    /**
     * 测试发私信界面是否正常显示
     */
    public void postMessageRight() throws InterruptedException {
        //先登录进入论坛首页
        Utils.login();
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(3)); //显示等待
        wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("#article_list_board_title")));

        //点击CPP
        WebElement target = Utils.slidePage("#artical-items-body > div:nth-child(12) > div > div.col > div.text-truncate > a > strong");
        //点击进入到帖子详情页
        target.click();

        Utils.slidePage("#btn_details_send_message");
        //点击作者下面的发私信按钮, 出现发送站内信界面
        driver.findElement(By.cssSelector("#btn_details_send_message")).click();

        driver.findElement(By.cssSelector("#index_message_modal > div > div > div.modal-header > h5"));
        driver.findElement(By.cssSelector("#btn_index_send_message"));
    }

    /**
     * 测试成功发送私信
     */
    public void postMessageSuc() throws IOException, InterruptedException {
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(3)); //显示等待

        //在发送私信窗口的输入框输入内容
        driver.findElement(By.cssSelector("#index_message_receive_content")).sendKeys("你好,小美");
        //点击发送按钮
        Thread.sleep(1000);
        driver.findElement(By.cssSelector("#btn_index_send_message")).click();

        Thread.sleep(1000);
        getScreenShot(getClass().getName());
    }

    /**
     * 测试站内信列表界面正常显示
     */
    public void messageListRight() throws InterruptedException, IOException {

        WebElement target = Utils.slidePage("body > div.page > header.navbar.navbar-expand-md.navbar-light.d-print-none > div > div > div:nth-child(2) > div > a");
        //点击右上角的铃铛
        driver.findElement(By.cssSelector("body > div.page > header.navbar.navbar-expand-md.navbar-light.d-print-none > div > div > div:nth-child(2) > div > a")).click();
        //出现站内信列表
        driver.findElement(By.cssSelector("#offcanvasEndLabel"));

        Thread.sleep(1000);
        getScreenShot(getClass().getName());
    }

    /**
     * 测试回复站内信
     */

    public void replyMessage() throws InterruptedException, IOException {
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(3)); //显示等待

        //找到某一条站内信, 点击
        driver.findElement(By.cssSelector("#index_div_message_list > div > div > div.col.text-truncate > a")).click();
        //点击回复按钮
        wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#btn_index_message_reply")));
        WebElement replyButton = driver.findElement(By.cssSelector("#btn_index_message_reply"));
        replyButton.click();
        //向输入框输入内容
        wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#index_message_reply_receive_content")));
        driver.findElement(By.cssSelector("#index_message_reply_receive_content")).sendKeys("回复内容");
        //点击发送
        driver.findElement(By.cssSelector("#btn_index_send_message_reply")).click();
        getScreenShot(getClass().getName());

    }
}

3.8 我的帖子 MyPostPage

  1. MyPostPageRight():测试我的帖子界面是否正常显示
  2. DetailPageRight():测试帖子详情是否可以正常访问,详情页是否正常显示
代码语言:javascript
复制
package test;

import common.Utils;
import jdk.jshell.execution.Util;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.io.IOException;
import java.time.Duration;

/**
 * 测试我的帖子界面是否正常显示
 */
public class MyPostPage extends Utils {
    public static String url = "http://62.234.142.221:58080/sign-in.html";

    public MyPostPage() {
        super(url);
    }

    /**
     * 测试我的帖子界面是否正常显示
     */
    public void MyPostPageRight() throws IOException {
        Utils.login();
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(3)); //显示等待

        //点击右上角头像
        WebElement element = driver.findElement(By.cssSelector("body > div.page > header.navbar.navbar-expand-md.navbar-light.d-print-none > div > div > div.nav-item.dropdown > a"));
        element.click();
        //点击我的帖子
        wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#index_user_profile")));
        driver.findElement(By.cssSelector("#index_user_profile")).click();

        //进入我的帖子界面
        wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("#index_user_profile")));
    }

    /**
     * 测试帖子详情是否可以正常访问,详情页是否正常显示
     */
    public void DetailPageRight() throws InterruptedException {
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(3)); //显示等待

        //点击进入帖子详情页
        Thread.sleep(2000);
        driver.findElement(By.cssSelector("#profile_article_body > li:nth-child(1) > div.card.timeline-event-card > div > div > div > div > div.text-truncate > a")).click();
        //测试页面元素
        wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("#details_article_title")));
        driver.findElement(By.cssSelector("#details_article_title"));
        driver.findElement(By.cssSelector("#details_btn_like_count"));
    }

}

3.9 个人中心 PersonalCenterPage

  1. PersonalCenterPageRight():个人中心界面是否正常显示
  2. modifyInfoSuc():测试修改个人信息
  3. modifyPasswordSuc():测试修改密码
代码语言:javascript
复制
package test;

import common.Utils;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.io.IOException;
import java.time.Duration;

/**
 * 测试个人中心界面相关功能
 */
public class PersonalCenterPage extends Utils {
    public static String url = "http://62.234.142.221:58080/sign-in.html";
    public PersonalCenterPage() {
        super(url);
    }

    public void PersonalCenterPageRight() {
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(3)); //显示等待
        //先登录进入论坛首页
        Utils.login();
        //点击右上角头像
        driver.findElement(By.cssSelector("body > div.page > header.navbar.navbar-expand-md.navbar-light.d-print-none > div > div > div.nav-item.dropdown > a")).click();
        //点击个人中心
        driver.findElement(By.cssSelector("#index_user_settings")).click();
        //检查页面是否正常加载
        wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("#\\34 04Lounge-content > div.page-body > div > div > div > div.col.d-flex.flex-column > div > div.row.align-items-center > div:nth-child(2) > a")));
        driver.findElement(By.cssSelector("#setting_submit_nickname"));
        driver.findElement(By.cssSelector("#settings_nickname"));
    }

    public void modifyInfoSuc() throws InterruptedException, IOException {

        //对于昵称,邮箱地址,电话,个人介绍, 任意一项都可以直接修改, 这里以昵称作为测试用例
        driver.findElement(By.cssSelector("#setting_input_nickname")).clear();

        //修改昵称
        String oldNickname = driver.findElement(By.cssSelector("#settings_nickname")).getText();
        //输入新昵称
        driver.findElement(By.cssSelector("#setting_input_nickname")).sendKeys(oldNickname + "1");
        //点击修改
        driver.findElement(By.cssSelector("#setting_submit_nickname")).click();
        getScreenShot(getClass().getName());


        //修改邮箱地址
        WebElement email = Utils.slidePage("#setting_input_email");
        email.clear();
        email.sendKeys("6666@qq.com");
        driver.findElement(By.cssSelector("#setting_submit_email")).click();
        getScreenShot(getClass().getName());

        //修改电话号码
        WebElement phone = Utils.slidePage("#setting_input_email");
        phone.clear();
        phone.sendKeys("887654321");
        driver.findElement(By.cssSelector("#setting_submit_phoneNum"));
        getScreenShot(getClass().getName());

        //修改个人简介
        WebElement info = Utils.slidePage("#settings_textarea_remark");
        info.clear();
        info.sendKeys("测试修改个人简历");
        driver.findElement(By.cssSelector("#settings_submit_remark"));
        getScreenShot(getClass().getName());
    }

    /**
     * 测试修改密码
     */

    public void modifyPasswordSuc() throws InterruptedException, IOException {
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(3)); //显示等待


        WebElement target = Utils.slidePage("#settings_submit_password");
        driver.findElement(By.cssSelector("#settings_input_oldPassword")).sendKeys("123456");
        //模拟修改密码
        driver.findElement(By.cssSelector("#settings_input_newPassword")).sendKeys("123456");
        driver.findElement(By.cssSelector("#settings_input_passwordRepeat")).sendKeys("123456");

        //点击提交修改
        driver.findElement(By.cssSelector("#settings_submit_password")).click();
        //跳转至登录界面
        getScreenShot(getClass().getName());
    }
}

4.接口测试

4.1 登录接口

4.2 板块接口

4.3 文章接口

4.4 回复接口

4.5 站内信接口

5.性能测试

5.1 聚合报告

5.2 TPS可视化

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

1.图表元素

  • 横轴:时间(Elapsed time),粒度为 1 秒,覆盖测试全程(约 1 分 11 秒)。
  • 纵轴:每秒事务数(Number of transactions/sec),反映接口每秒能处理的成功请求数。
  • 多色折线:每条折线对应一个系统接口,图例标注了接口类型(如 “登录接口”“获取帖子列表”“点赞” 等),且均为 “success”,代表成功事务的吞吐量。

2.吞吐量趋势

  • 核心接口(如 “登录接口”):前期吞吐量波动剧烈,多次达到 60+ transactions/sec 的峰值,但后期急剧下降,说明该接口在高负载场景下处理能力不稳定,可能存在并发瓶颈或资源限制。
  • 其他接口(如 “获取板块信息”“未读消息个数” 等):吞吐量相对平稳,维持在较低水平,表明这些接口的并发处理压力较小,性能表现稳定。

5.3 响应时间可视化

1.图表结构与元素

  • 横轴:时间(从00:00:0000:01:10左右),反映测试的时间进程。
  • 纵轴:响应时间(单位ms),体现接口处理请求的耗时。
  • 多色折线:每条折线对应一个系统接口,图例标注了接口类型,如 “登录接口”“获取帖子列表”“点赞”“回复帖子” 等。

2.性能趋势分析

  • 前期(00:00:00 - 00:00:45):多数接口响应时间稳定,基本在10000ms以内,系统性能表现平稳。
  • 后期(00:00:45 之后):“获取帖子列表”“登录接口” 等核心接口响应时间急剧攀升,甚至突破60000ms,说明系统在持续负载或高并发场景下出现性能衰减,可能存在数据库查询瓶颈、接口并发控制不足或服务器资源(如 CPU、内存)过载等问题。

5.4 性能测试报告

代码语言:javascript
复制
jmeter -n -t 404Lounge.jmx -l report.jtl -e -o 404LoungeReport

错误概述:

本次性能测试中,“获取回复列表” 接口出现1 次错误,错误类型为TruncatedChunkException(HTTP 分块传输截断异常)。具体指标如下:

  • 总样本数:2906 次
  • 错误样本数:1 次
  • 错误占比:0.03%(占总样本)、100%(占所有错误)

可能原因分析:

1.网络波动

  • 测试环境或生产环境的网络链路不稳定(如丢包、延迟突然升高、带宽拥堵),导致请求 / 响应数据传输耗时增加。
  • 客户端与服务器之间的网络路由跳转过多,也可能引发响应时间波动。

2.并发请求处理能力不足

  • 同一时间发起大量请求(如批量获取数据、高并发场景),服务器资源(CPU、内存、线程池)被占满,无法及时处理新请求,导致排队等待时间过长。

6.兼容性测试

场景一:以chrome浏览器进行测试

场景二:以edge浏览器进行测试

7.安全测试

场景一:未登录状况下,是否能访问除登陆外的其它板块 结果:无法访问除登陆外的其它板块

场景二: 用户密码是否在数据库加密 结果:用户密码在数据库中已加密

8.网络测试

有网络情况下可以正常访问网页

无网络情况下无法访问网页

9.Bug描述

网络抓包登录接口明文显示

并发修改数据,数据不同步

10.测试总结

测试用例设计与执行

基于论坛系统注册、登录、首页、发帖、帖子详情、站内信、我的帖子、个人中心8 大核心模块,共设计99 条功能测试用例,执行测试覆盖率98%,通过有效测试用例99 条,遗留待优化问题 7 条(主要为界面交互细节优化)。

自动化测试

针对公共类 Utils 及 8 大界面(注册、登录、论坛首页、发帖、帖子详情、站内信、我的帖子、个人中心)

  • 公共类 Utils:设计 5 条用例,全部通过,保障工具类方法的通用性和稳定性。
  • 注册 / 登录界面:共设计 8 条用例,分别通过 8 条,重点验证账号注册、密码校验、登录态保持等核心流程;
  • 论坛首页 / 发帖 / 帖子详情:共设计 10 条用例,分别通过 10条,覆盖帖子列表渲染、发帖格式校验、评论交互等场景;
  • 站内信 / 我的帖子 / 个人中心:共设计 9 条用例,全部通过,验证消息收发、帖子管理、个人信息修改等功能;

接口测试

围绕用户注册、登录、发帖、评论、站内信等 16 个核心接口,设计 16 条接口测试用例,测试覆盖率95%,通过有效用例21 条,发现并修复接口逻辑漏洞 4 处。

性能测试

通过jmeter工具模拟多线程高并发来对论坛系统的多个接口进行性能测试

1.聚合报告

  • 总请求数3808,总吞吐量53.8/sec,平均响应时间190.76(综合各接口),错误率 0.00%。系统全业务场景实现 “全接口成功、高吞吐、低延迟”,性能符合预期。

2.TPS可视化

  • 共覆盖15 类核心业务接口,包括登录、帖子全生命周期管理(发布 / 修改 / 删除 / 详情)、站内信交互(发送 / 回复 / 查询)、板块信息查询(首页板块 / 某板块)、互动点赞等,所有接口均标注 “(success)”,执行成功率 100%
  • 在测试期间各核心接口性能达标且无执行失败,登录接口峰值 TPS 约 65 transactions/sec,其他接口负载平稳、处理能力充足,整体满足高并发场景下的性能需求。

3.响应时间可视化

  • 登录接口、站内信交互(发送 / 回复)、帖子增删改、板块查询等接口:在测试周期内响应时间整体平稳,波动幅度小,维持在10,000 ms 以内,性能表现稳定
  • 获取帖子列表(紫色曲线)、获取回复列表(红色曲线):是系统中数据量最大、业务逻辑最复杂的接口,响应时间在测试后期急剧攀升,峰值分别接近65,000 ms63,000 ms
  • 大部分业务接口响应性能达标,但 “获取帖子列表”“获取回复列表” 在高并发后期存在严重性能瓶颈

兼容性测试

  • 基于论坛系统主流 PC 系统(Linux/Windows/Mac)、主流移动端系统(Android/iOS/Harmony Next)、主流浏览器(Chrome/FireFox/IE/Edge)、多分辨率场景,共设计11 条兼容性测试用例,执行测试覆盖率100%,通过有效测试用例11 条,测试通过率100%

安全测试

  • 针对SQL 注入、权限越界、密码明文传输等风险点,设计3 条安全测试用例,通过率100%

网络测试

  • 验证4G、5G、Wi-Fi、无网络网络环境下的访问稳定性,设计4 条网络测试用例,通过率100%,全网络环境下论坛功能均可正常使用。
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-11-13,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.项目背景
    • 1.1 项目简介
    • 1.2 应用技术
  • 2.项目模块及实现功能
  • 2.测试用例
  • 3.自动化测试
    • 3.1 公共类 Utils
    • 3.2 注册界面 RegisterPageTest
    • 3.3 登陆界面 LoginPage
    • 3.4 论坛首页 HomePage
    • 3.5 发帖界面 PublishPage
    • 3.6 帖子详情 DetailsPage
    • 3.7 站内信 MessagePage
    • 3.8 我的帖子 MyPostPage
    • 3.9 个人中心 PersonalCenterPage
  • 4.接口测试
    • 4.1 登录接口
    • 4.2 板块接口
    • 4.3 文章接口
    • 4.4 回复接口
    • 4.5 站内信接口
  • 5.性能测试
    • 5.1 聚合报告
    • 5.2 TPS可视化
    • 5.3 响应时间可视化
    • 5.4 性能测试报告
  • 6.兼容性测试
  • 7.安全测试
  • 8.网络测试
  • 9.Bug描述
  • 10.测试总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档