【话题长廊测试报告】
文章目录
- 话题长廊测试报告
- 1、项目背景
- (1)项目简介
- (2)测试目标
- (3)被测系统
- (4)后端接口
- (5)接口文档
- 2、测试安排
- 3、测试分类
- (1)功能测试
- 用户模块
- 帖子模块
- (2)自动化测试
- 4、遗留风险
- 5、测试结果评估
话题长廊测试报告
项目名称 | 话题长廊 | 版本号 | v1.0 |
---|---|---|---|
发布类型 | 分级发布 | 测试负责人 | zyz |
测试完成日期 | 2025.07.08 | 联系方式 | 136-xxxx-xxxx |
审批人 | 审批人A | 批准人 | 产品人A |
评审日期 | 2025.07.09 | 批准日期 | 2025.07.09 |
1、项目背景
(1)项目简介
本论坛系统基于SSM框架并结合JWT技术搭建。该系统为用户提供了一个活跃的交流平台。用户可以发布主题帖、回复帖 子,进行知识分享和讨论。系统具有清晰的板块分类,方便用户快速找到感兴趣的话题。通过 JWT 实现安全的用户认证和授权,确 保用户数据安全。SSM 框架保证了系统的稳定性和高效性,能够处理大量的用户请求。
(2)测试目标
制定详细测试计划,对论坛系统的各项功能进行全面测试,确保功能符合需求,及时发现并记录功能缺陷。针对 JWT 认证授权机制进行安全测试,检查用户数据的安全性和保密性,防止非法访问和数据泄露。测试系统在不同浏览器和操作系统上的兼容性,确保用户在各种环境下都能正常使用论坛系统。
(3)被测系统
话题长廊系统gitee链接
(4)后端接口
模块 | 接口 | 请求方式 | 作用 |
---|---|---|---|
用户模块 /user | register | Post | 用户注册 |
login | Post | 用户登录 | |
logout | Get | 退出登录 | |
info | Get | 获取用户信息 | |
modifyInfo | Post | 修改个人信息 | |
ModifyPwd | Post | 修改密码 | |
板块模块 /board | topList | Get | 获取首页板块信息 |
GetById | Get | 根据 id 获取板块信息 | |
帖子模块 /article | create | Post | 发布新帖 |
GetAllByBoardId | Get | 获取帖子列表 | |
Details | Get | 根据 id 查询帖子详情 | |
Modify | Get | 修改帖子 | |
ThumbsUpById | Post | 点赞帖子 | |
Delete | Post | 删除帖子 | |
GetAllByUserId | Get | 获取用户的帖子列表 | |
帖子回复模块 /reply | Create | Get | 回复帖子 |
GetReplies | Get | 获取回复列表 | |
站内信模块 /message | send | Post | 发送站内信 |
GetUnreadCount | Get | 获取未读数 | |
GetAll | Get | 查询用户所有的站内信 | |
MarkRead | Post | 更新为已读 | |
Reply | Post | 回复站内信 |
…
(5)接口文档
2、测试安排
模块 | 子模块 | 前端 | 开发 | 提测时间 | 测试 | 工时 | 排期 | 进度 | 备注 |
---|---|---|---|---|---|---|---|---|---|
登录 | 登录功能 | 前端A | 开发B | 7.8 | 测试大王 | 0.3d | 7.8 | 提测完成 | 无 |
发布帖子 | 发布帖子 | 前端A | 开发B | 7.8 | 测试大王 | 0.3d | 7.8 | 提测完成 | 无 |
编辑帖子 | 编辑帖子 | 前端A | 开发B | 7.8 | 测试大王 | 0.2d | 7.8 | 提测完成 | 无 |
删除帖子 | 删除帖子 | 前端A | 开发B | 7.8 | 测试大王 | 0.1d | 7.8 | 提测完成 | 无 |
点赞帖子 | 点赞帖子 | 前端A | 开发B | 7.8 | 测试大王 | 0.1d | 7.8 | 提测完成 | 无 |
评论帖子 | 评论帖子 | 前端A | 开发B | 7.9 | 测试大王 | 0.2d | 7.9 | 提测完成 | 无 |
退出 | 退出 | 前端A | 开发B | 7.9 | 测试大王 | 0.2d | 7.9 | 提测完成 | 无 |
3、测试分类
(1)功能测试
用户模块
用户注册
用户登录
我的帖子
个人中心
站内信
帖子模块
帖子大厅
发布帖子
帖子详情
功能测试结果:功能测试结果:测试用例99%通过
(2)自动化测试
/*** 用户模块测试*/
public class User {// 拿到driverprivate final WebDriver driver = WebDriverUtil.getDriver();// 设置全局显示等待时间private final WebDriverWait driverWait = new WebDriverWait(driver, Duration.ofSeconds(5));/*** 测试登录功能*/public void loginAndExit(String username,String password) {// 拿到方法名String functionName = Thread.currentThread().getStackTrace()[1].getMethodName();// 登陆界面driver.get("http://127.0.0.1:1010/sign-in.html");// 检查logo显示状态By logoBy = By.cssSelector("body > div.page.page-center > div > div > div:nth-child(1) > div > div.text-center.mb-4 > img");driverWait.until(ExpectedConditions.presenceOfElementLocated(logoBy));// 检查背景图是否正常加载By image = By.cssSelector("body > div.page.page-center > div > div > div.col-lg.d-none.d-lg-block > img");driverWait.until(ExpectedConditions.presenceOfElementLocated(image));loginInput(driverWait, driver, functionName, username, password);// 判断是否正确跳转WebElement isAvatarExit = driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#index_nav_avatar")));if (isAvatarExit != null) {System.out.println("登陆成功测试完毕");}// 测试登录失败// 跳转回登录界面 - 退出登录driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#index_nav_avatar"))).click();// 点击退出按钮driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#index_user_logout > span"))).click();loginInput(driverWait, driver, functionName, "admin", "111111");// 查看错误提醒是否存在By failBy = By.cssSelector("body > div.jq-toast-wrap.bottom-right > div");driverWait.until(ExpectedConditions.visibilityOfElementLocated(failBy));System.out.println("登陆失败测试完毕");}/*** 测试注册功能*/public void register(String username,String nickname,String password) {// 拿到方法名String functionName = Thread.currentThread().getStackTrace()[1].getMethodName();// 登陆界面driver.get("http://127.0.0.1:1010/sign-in.html");// 点击注册按钮跳转至注册界面By registerBy = By.cssSelector("body > div > div > div > div:nth-child(1) > div > div.text-center.text-muted.mt-3 > a");driverWait.until(ExpectedConditions.visibilityOfElementLocated(registerBy)).click();// 查看是否跳转到注册界面String title = driverWait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("#signUpForm > div > h2"))).getText();if (!"用户注册".equals(title)) throw new AppException("用户注册界面加载异常");// 用户名driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#username"))).sendKeys(username);// 昵称driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#nickname"))).sendKeys(nickname);// 密码driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#password"))).sendKeys(password);// 确认密码driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#passwordRepeat"))).sendKeys(password);// 同意条款driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#policy"))).click();// 点击注册按钮driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#submit"))).click();// 检查页面是否跳转至登录界面String loginTitle = driverWait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("body > div > div > div > div:nth-child(1) > div > div.card.card-md > div > h2"))).getText();if (!"用户登录".equals(loginTitle)) throw new AppException("用户注册结果异常");System.out.println("注册成功测试完毕");// 测试失败注册(两次注册密码不一致)// 点击注册按钮跳转至注册界面By registerByNew = By.cssSelector("body > div > div > div > div:nth-child(1) > div > div.text-center.text-muted.mt-3 > a");driverWait.until(ExpectedConditions.visibilityOfElementLocated(registerByNew)).click();// 查看是否跳转到注册界面String titleNew = driverWait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("#signUpForm > div > h2"))).getText();if (!"用户注册".equals(titleNew)) throw new AppException("用户注册界面加载异常");// 用户名driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#username"))).sendKeys(username + 1);// 昵称driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#nickname"))).sendKeys(username + 1);// 密码driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#password"))).sendKeys(password+1);// 确认密码driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#passwordRepeat"))).sendKeys(password+2);// 同意条款driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#policy"))).click();// 点击注册按钮driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#submit"))).click();// 检查页面情况String passwordErr = driverWait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("#signUpForm > div > div:nth-child(5) > div > div"))).getText();if (!"请检查确认密码".equals(passwordErr)) throw new AppException("用户注册结果异常");System.out.println("注册失败测试完毕");}/*** 我的帖子测试*/public void userHistoryPost(String username, String password) {// 拿到方法名String functionName = Thread.currentThread().getStackTrace()[1].getMethodName();// 登陆界面driver.get("http://127.0.0.1:1010/sign-in.html");// 检查logo显示状态By logoBy = By.cssSelector("body > div.page.page-center > div > div > div:nth-child(1) > div > div.text-center.mb-4 > img");driverWait.until(ExpectedConditions.presenceOfElementLocated(logoBy));// 检查背景图是否正常加载By image = By.cssSelector("body > div.page.page-center > div > div > div.col-lg.d-none.d-lg-block > img");driverWait.until(ExpectedConditions.presenceOfElementLocated(image));loginInput(driverWait, driver, functionName, username, password);// 进入到大厅之后 点击右上角头像driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#index_nav_avatar"))).click();// 点击我的帖子driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("body > div.page > header.navbar.navbar-expand-md.navbar-light.d-print-none > div > div" +" > div.nav-item.dropdown > div > #index_user_profile"))).click();// 查看本界面元素是否展示// 昵称driverWait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("#bit-forum-content > div.page-" +"header.d-print-none > div > div > div> #profile_nickname")));// 头像driverWait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("#bit-forum-content > div.page-header" +".d-print-none > div > div > div> #profile_avatar")));// 界面展示成功System.out.println("我的帖子测试完毕");}public void userCenter(String imageUrl,String nikeName,String password, String newPassword, String email, String phoneNumber, String myCard) throws InterruptedException {// 拿到方法名String functionName = Thread.currentThread().getStackTrace()[1].getMethodName();// 点击右上角我的头像driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("body > div.page > header.navbar" +".navbar-expand-md.navbar-light.d-print-none > div > div > div.nav-item.dropdown >a> #index_nav_avatar"))).click();// 选中个人中心driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("body > div.page > header.navbar" +".navbar-expand-md.navbar-light.d-print-none > div > div > div.nav-item.dropdown > div>#index_user_settings"))).click();// 检查是否正常跳转个人中心页面String title = driverWait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("#bit-forum-content > div.page-header.d-print-none > div > div > div > h2"))).getText();if (!"用户中心".equals(title)) throw new AppException("用户中心加载异常");// 检查各个输入元素是否正常展示// 头像driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#bit-forum-content > div.page-body > div > div > div > div.col.d-flex.flex-column > " +"div > div.row.align-items-center > div:nth-child(2) > a")));// 上传一个头像driverWait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("#settings_input_chooiceAvatar"))).sendKeys(imageUrl);// 跳转到大厅String mainTitle = driverWait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("#bit-forum-content > div.page-header.d-print-none" +" > div > div > div.col>#article_list_board_title"))).getText();if (!"首页".equals(mainTitle)) throw new AppException("头像上传失败") ;System.out.println("头像上传完毕");// 点击右上角我的头像driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("body > div.page > header.navbar" +".navbar-expand-md.navbar-light.d-print-none > div > div > div.nav-item.dropdown >a> #index_nav_avatar"))).click();// 选中个人中心driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("body > div.page > header.navbar" +".navbar-expand-md.navbar-light.d-print-none > div > div > div.nav-item.dropdown > div>#index_user_settings"))).click();// 检查是否正常跳转个人中心页面String currentTitle = driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#bit-forum-content > div.page-header.d-print-none > div > div > div > h2"))).getText();if (!"用户中心".equals(currentTitle)) throw new AppException("用户中心加载异常");// 昵称输入框WebElement nikeNameElem = driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#bit-forum-content > div.page-body " +"> div > div > div > div.col.d-flex.flex-column > div > div:nth-child(5)>div>#setting_input_nickname")));nikeNameElem.clear();nikeNameElem.sendKeys(nikeName);driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#bit-forum-content > div.page-body" +" > div > div > div > div.col.d-flex.flex-column > div > div:nth-child(5)>div>#setting_submit_nickname"))).click();String nikeNameResult = driverWait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("body > div.jq-toast-wrap.bottom-right > div > h2"))).getText();if (!"success".equals(nikeNameResult)) throw new AppException("昵称修改异常");System.out.println("昵称修改完毕");// 邮箱输入框WebElement emailElem = driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#bit-forum-content > div.page-body " +"> div > div > div > div.col.d-flex.flex-column > div > div:nth-child(8) > div>div>#setting_input_email")));emailElem.clear();emailElem.sendKeys(email);driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#bit-forum-content > div.page-body > div > " +"div > div > div.col.d-flex.flex-column > div > div:nth-child(8) > div>div>#setting_submit_email"))).click();String emailResult = driverWait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("body > div.jq-toast-wrap.bottom-right > div > h2"))).getText();if (!"success".equals(emailResult)) throw new AppException("邮箱修改异常");System.out.println("邮箱修改完毕");// 电话号码输入框WebElement phoneElem = driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#bit-forum-content > div.page-body > div > div" +" > div > div.col.d-flex.flex-column > div > div:nth-child(11) > div>div>#setting_input_phoneNum")));phoneElem.clear();phoneElem.sendKeys(phoneNumber);WebElement phoneButtonElem = driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#bit-forum-content > div.page-body >" +" div > div > div > div.col.d-flex.flex-column > div > div:nth-child(11) > div > div.col-3>#setting_submit_phoneNum")));ScrollUtil.scrollToElement(driver,phoneButtonElem);Thread.sleep(500);phoneButtonElem.click();String phoneNumberResult = driverWait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("body > div.jq-toast-wrap.bottom-right > div > h2"))).getText();if (!"success".equals(phoneNumberResult)) throw new AppException("电话号码修改异常");System.out.println("电话号码修改完毕");// 个人简介WebElement myCardElem = driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#bit-forum-content > div.page-body > div > div > div >" +" div.col.d-flex.flex-column > div > div:nth-child(17) > div.col-9 > #settings_textarea_remark")));myCardElem.clear();myCardElem.sendKeys(myCard);// 自动滚动WebElement myCardButtonElem = driverWait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#bit-forum-content > div.page-body >" +" div > div > div > div.col.d-flex.flex-column > div > div:nth-child(17) > div.col-3 > #settings_submit_remark")));ScrollUtil.scrollToElement(driver,myCardButtonElem);Thread.sleep(500);((JavascriptExecutor)driver).executeScript("arguments[0].click()",myCardButtonElem);String myCardResult = driverWait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("body > div.jq-toast-wrap.bottom-right > div > h2"))).getText();if (!"success".equals(myCardResult)) throw new AppException("个人简介修改异常");System.out.println("个人简介修改完毕");// 原密码driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#bit-forum-content > div.page-body > div > div > div > " +"div.col.d-flex.flex-column > div > div:nth-child(14) > div > div > form > div:nth-child(1) > div > #settings_input_oldPassword"))).sendKeys(password);// 新密码driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#bit-forum-content > div.page-body > div > div > div > " +"div.col.d-flex.flex-column > div > div:nth-child(14) > div > div > form > div:nth-child(2)>div>#settings_input_newPassword"))).sendKeys(newPassword);// 确认密码driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#bit-forum-content > div.page-body > div > div > div > " +"div.col.d-flex.flex-column > div > div:nth-child(14) > div > div > form > div:nth-child(3) > div >#settings_input_passwordRepeat"))).sendKeys(newPassword);driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#bit-forum-content > div.page-body > div > div > div > " +"div.col.d-flex.flex-column > div > div:nth-child(14) > div > div > form > div.form-footer > button"))).click();// 跳转到登录界面表示修改成功String loginTitle = driverWait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("body > div > div > div > div:nth-child(1) > div > div.card.card-md > div > h2"))).getText();if (!"用户登录".equals(loginTitle)) throw new AppException("密码修改异常");System.out.println("用户中心测试完毕");}private static void loginInput(WebDriverWait driverWait, WebDriver driver, String functionName, String userName, String password) {// 检查输入By userInputBy = By.cssSelector("#username");By passwordBy = By.cssSelector("#password");WebElement userInputElem = driverWait.until(ExpectedConditions.presenceOfElementLocated(userInputBy));if (userInputElem == null) {ScreenshotUtil.screenshot(driver, functionName);throw new AppException("用户名输入框加载异常");}WebElement passwordElem = driverWait.until(ExpectedConditions.presenceOfElementLocated(passwordBy));if (passwordElem == null) {ScreenshotUtil.screenshot(driver, functionName);throw new AppException("密码输入框加载异常");}// 检查按钮By submitBy = By.cssSelector("#submit");WebElement submitElem = driverWait.until(ExpectedConditions.presenceOfElementLocated(submitBy));if (submitElem == null) {ScreenshotUtil.screenshot(driver, functionName);throw new AppException("登陆按钮加载异常");}userInputElem.sendKeys(userName);passwordElem.sendKeys(password);submitElem.click();}
}
/*** 帖子模块测试*/
public class Invitation {private static final WebDriver driver = WebDriverUtil.getDriver();private static final WebDriverWait driverWait = new WebDriverWait(driver, Duration.ofSeconds(5));/*** 发布帖子*/public void addInvitation(String username, String password ,String title, String content) throws InterruptedException {String methodName = Thread.currentThread().getStackTrace()[1].getMethodName();driver.get("http://127.0.0.1:1010/sign-in.html");// 检查logo显示状态By logoBy = By.cssSelector("body > div.page.page-center > div > div > div:nth-child(1) > div > div.text-center.mb-4 > img");driverWait.until(ExpectedConditions.presenceOfElementLocated(logoBy));// 检查背景图是否正常加载By image = By.cssSelector("body > div.page.page-center > div > div > div.col-lg.d-none.d-lg-block > img");driverWait.until(ExpectedConditions.presenceOfElementLocated(image));loginInput(driverWait, driver, methodName, username, password);// 判断是否正确跳转WebElement isAvatarExit = driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#index_nav_avatar")));if (isAvatarExit != null) {System.out.println("登陆成功测试完毕");}// 点击发布帖子按钮driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#bit-forum-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();// 查看跳转String publishTitle = driverWait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("#bit-forum-content > " +"div.page-header.d-print-none > div > div > div > h2"))).getText();if (!"发新贴".equals(publishTitle)) throw new AppException("跳转帖子发布界面失败");driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#bit-forum-content > div.page-body " +"> div > div > div.card-body > div:nth-child(1) > select"))).click();// 选中下拉框中的面试宝典driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#article_post_borad > option:nth-child(5)"))).click();// 选中标题输入框driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#bit-forum-content > div.page-body > div " +"> div > div.card-body > div:nth-child(2) > input"))).sendKeys(title);// 选中内容框 输入内容// CodeMirror 编辑器是一种特殊的富文本编辑器,直接向内部元素输入可能无效。需要通过 JavaScript 调用其 API:String script = "var editor = document.querySelector('.CodeMirror').CodeMirror;editor.setValue('"+ content +"');";((JavascriptExecutor)driver).executeScript(script);// 点击发布按钮WebElement button = driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#bit-forum-content > div.page-body " +"> div > div > div.card-footer.bg-transparent.mt-auto > div >#article_post_submit")));ScrollUtil.scrollToElement(driver,button);Thread.sleep(500);button.click();// 跳转首页表示成功String mainTitle = driverWait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("#artical-items-body > div:nth-child(1) > div > div.col > div.text-truncate > a > strong"))).getText();if (!title.equals(mainTitle)) throw new AppException("帖子发布失败");System.out.println("发布帖子测试完毕");}/*** 点赞和评论回复* @param content*/public void addLikeAndReply(String content) throws InterruptedException {String methodName = Thread.currentThread().getStackTrace()[1].getMethodName();// 找到对应的标题帖子driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#artical-items-body > div:nth-child(1) > div > div.col > div.text-truncate > a > strong"))).click();// 查看界面跳转情况driverWait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("#bit-forum-content > div.page-body " +"> div > div > div:nth-child(1) > div.col-9.card.card-lg > div.card-body > #details_article_content_title")));// 定位点赞按钮driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#bit-forum-content > div.page-body " +"> div > div > div:nth-child(1) > div.col-9.card.card-lg > div.card-footer.bg-transparent.mt-auto.justify-content-end " +"> div > div:nth-child(1) > div > #details_btn_like_count"))).click();// 是否点赞成功String likeSuccess = driverWait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("body > div.jq-toast-wrap.bottom-right > div > h2"))).getText();if (!"success".equals(likeSuccess)) throw new AppException("点赞异常");// 找到评论框输入内容String script = "var editor = document.querySelector('.CodeMirror').CodeMirror;editor.setValue('"+ content +"');";((JavascriptExecutor)driver).executeScript(script);// 点击回复按钮WebElement buttonElem = driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#details_btn_article_reply > span")));ScrollUtil.scrollToElement(driver,buttonElem);Thread.sleep(500);((JavascriptExecutor)driver).executeScript("arguments[0].click()",buttonElem);// 查看是否回复成功Thread.sleep(500);String replay = driverWait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("#details_reply_area > div:nth-child(1) > div:nth-child(2) > div > div > p"))).getText();if (!content.equals(replay)) throw new AppException("回复失败");System.out.println("点赞评论测试完毕");}/*** 帖子编辑*/public void editInvitation(String newTitle, String newContent) throws InterruptedException {String methodName = Thread.currentThread().getStackTrace()[1].getMethodName();Thread.sleep(500);// 点击进入帖子详情页driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#artical-items-body > div:nth-child(1) > div > div.col > div.text-truncate > a > strong"))).click();// 滚动界面找到编辑按钮WebElement editButtonElem = driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#bit-forum-content > div.page-body" +" > div > div > div:nth-child(1) > div.col-9.card.card-lg > div.card-footer.bg-transparent.mt-auto.justify-content-end " +"> div > div:nth-child(2) > div > #details_artile_edit")));ScrollUtil.scrollToElement(driver,editButtonElem);Thread.sleep(500);editButtonElem.click();// 检查是否跳转到编辑页面String editTitle = driverWait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("#bit-forum-content > div.page-header.d-print-none" +" > div > div > div > h2"))).getText();if (!"编辑".equals(editTitle)) throw new AppException("跳转编辑页面失败");// 选中标题输入框WebElement titleInputElem = driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#bit-forum-content > div.page-body > div > div > div > div " +"> div.card-body > div:nth-child(3) > div.col-10>#edit_article_title")));titleInputElem.clear();titleInputElem.sendKeys(newTitle);// 选中内容框 输入内容// CodeMirror 编辑器是一种特殊的富文本编辑器,直接向内部元素输入可能无效。需要通过 JavaScript 调用其 API:String script = "var editor = document.querySelector('.CodeMirror').CodeMirror;editor.setValue('"+newContent+"');";((JavascriptExecutor)driver).executeScript(script);// 向下滚动到提交按钮WebElement buttonElem = driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#bit-forum-content > div.page-body >" +" div > div > div > div > div.card-footer.bg-transparent.mt-auto > div > div > div>#edit_article_submit")));ScrollUtil.scrollToElement(driver,buttonElem);Thread.sleep(500);// 点击按钮buttonElem.click();// 如果跳转到首页表示成功String mainTitle = driverWait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("#bit-forum-content > div.page-header.d-print-none" +" > div > div > div.col>#article_list_board_title"))).getText();if (!"首页".equals(mainTitle)) throw new AppException("编辑失败");System.out.println("编辑帖子测试完毕");}/*** 删除帖子*/public void deleteInvitation() {String methodName = Thread.currentThread().getStackTrace()[1].getMethodName();// 关闭站内信界面driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#index_message_offcanvasEnd > " +"div.offcanvas-header > button"))).click();// 点击进入帖子详情页driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#artical-items-body > div:nth-child(1)" +" > div > div.col > div.text-truncate > a > strong"))).click();// 查看跳转 定位删除按钮driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#bit-forum-content > div.page-body " +"> div > div > div:nth-child(1) > div.col-9.card.card-lg > div.card-footer.bg-transparent.mt-auto.justify-content-end " +"> div > div:nth-child(3) > div > a"))).click();// 定位弹窗中的删除按钮driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#details_delete_modal > div > " +"div > div.modal-footer > div > div > div:nth-child(2)>#details_artile_delete"))).click();// 跳转到首页表示成功String mainTitle = driverWait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector("#bit-forum-content > div.page-header.d-print-none" +" > div > div > div.col>#article_list_board_title"))).getText();if (!"首页".equals(mainTitle)) throw new AppException("帖子删除失败");System.out.println("删除帖子测试完毕");}/*** 站内信发送和回复*/public void siteMessage(String username1,String password1,String username2, String password2, String sendContent) {String methodName = Thread.currentThread().getStackTrace()[1].getMethodName();// 点击退出切换账号发送站内信driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("body > div.page > " +"header.navbar.navbar-expand-md.navbar-light.d-print-none > div > div > div.nav-item.dropdown > a >#index_nav_avatar"))).click();driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#index_user_logout > span"))).click();// 进行登录loginInput(driverWait,driver,methodName,username1,password1);// 点击进入帖子详情driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#artical-items-body > div > div " +"> div.col > div.text-truncate > a > strong"))).click();// 点击发私信按钮driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#div_details_send_message>" +"#btn_details_send_message"))).click();// 选中内容输入框driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#index_message_modal > div > " +"div > div.modal-body > div > div > div>#index_message_receive_content"))).sendKeys(sendContent);// 点击发送按钮driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#index_message_modal > div > " +"div > div.modal-footer>#btn_index_send_message"))).click();// 如果右下角出现了弹窗表示成功String successStr = driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("body > div.jq-toast-wrap.bottom-right > div > h2"))).getText();if (!"success".equals(successStr)) throw new AppException("站内信发送失败");// 发送成功后退出登录 使用username2进行查看driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("body > div.page > " +"header.navbar.navbar-expand-md.navbar-light.d-print-none > div > div > div.nav-item.dropdown > a >#index_nav_avatar"))).click();// 点击退出driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#index_user_logout > span"))).click();// 进行登录loginInput(driverWait,driver,methodName,username2,password2);// 点击右上角小铃铛driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("body > div.page >" +" header.navbar.navbar-expand-md.navbar-light.d-print-none > div > div > div:nth-child(2) > div > a > svg"))).click();// 如果有消息表示成功driverWait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("#index_div_message_list > div:nth-child(1) > " +"div > div.col.text-truncate > a")));System.out.println("站内信测试完毕");}private static void loginInput(WebDriverWait driverWait, WebDriver driver, String functionName, String userName, String password) {// 检查输入By userInputBy = By.cssSelector("#username");By passwordBy = By.cssSelector("#password");WebElement userInputElem = driverWait.until(ExpectedConditions.presenceOfElementLocated(userInputBy));if (userInputElem == null) {ScreenshotUtil.screenshot(driver, functionName);throw new AppException("用户名输入框加载异常");}WebElement passwordElem = driverWait.until(ExpectedConditions.presenceOfElementLocated(passwordBy));if (passwordElem == null) {ScreenshotUtil.screenshot(driver, functionName);throw new AppException("密码输入框加载异常");}// 检查按钮By submitBy = By.cssSelector("#submit");WebElement submitElem = driverWait.until(ExpectedConditions.presenceOfElementLocated(submitBy));if (submitElem == null) {ScreenshotUtil.screenshot(driver, functionName);throw new AppException("登陆按钮加载异常");}userInputElem.sendKeys(userName);passwordElem.sendKeys(password);submitElem.click();}
}
自动化测试覆盖模块:登录页面、注册页面、首页、文章编辑页
自动化代码示例:
话题长廊自动化测试gitee链接
自动化测试用例数量:20
自动化测试结果:pass:20/20、fail:0/20
自动化测试问题是否修复:是
4、遗留风险
话题长廊遗留风险URL
5、测试结果评估
(1)主功能测试通过,但还存在Bug建议优化后进行测试再上线
(2)项目上线后高优观察上线数据,查看线上用户操作日志,及时跟进用户反馈