当前位置: 首页 > news >正文

【博文汇项目全维度测试报告:功能与自动化双轨验证】

](https://img-home.csdnimg.cn/images/20220524100510.png#pic_center)
🌈个人主页: Aileen_0v0
🔥热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法
💫个人格言:“没有罗马,那就自己创造罗马~”

文章目录

  • 项目背景:
    • 项目背景与意义:
    • 项目概述
      • 已实现的主要功能包括:
      • 当前系统存在的不足:
    • 项目的系统功能说明
      • 1. 登录功能
      • 2. 博客列表页
      • 3. 博客详情页
      • 4. 博客编辑页
    • 测试目标:
    • 测试项目相关信息:
  • 测试安排:
  • 测试分类:
    • (1)功能测试
    • (2)自动化测试
    • ①编写Web测试用例:
    • ②创建空项目
      • (1)配置准备:添加需要的pom.xml依赖
      • (2)创建驱动对象driver
      • (3)测试用例的划分
    • 自动化测试工具准备:
    • 测试用例tests的编写:
      • ①登录页面:
        • 检查页面的正常加载:
        • 检查成功登录:
        • 检查登录失败:
      • ②列表页面测试:
      • ③编辑页面:
      • ④:详情页面:
    • (3)性能测试:
      • 模拟并发访问登录页面:
  • 总结测试 tips:

项目名称博文汇版本号/
发布类型分级发布测试负责人Aileen
测试完成日期7/9联系方式

项目背景:

项目背景与意义:

  • 随着互联网的发展,博客平台成为技术交流、知识分享的重要载体。CSDN作为国内知名的技术社区,为广大开发者提供了丰富的学习与交流资源。作为一名CSDN博主,我在日常写作和交流中深刻体会到一个高效、便捷、安全的博客系统对于个人成长和技术传播的重要性。因此,我以CSDN为参考,设计并开发了**“博文汇”**项目,旨在打造一个简洁易用、功能完善的个人博客平台,便于回顾所学的知识。
  • 本项目的创建不仅是对主流博客平台功能的实践和复现,更是对Web开发全流程的系统学习和能力提升。通过项目开发,我深入掌握了Java、Spring Boot、前端技术、JWT 令牌加密等关键技能,并在实际应用中强化了对安全性、用户体验、系统可维护性的理解,实现将自己所学的知识融会贯通到项目中,加深自己对技术的理解。
  • 若有不足或改进之处,也希望大家指出☺️~

项目概述

本项目实现了一个基于前后端分离架构的个人博客系统,采用数据库存储用户与博客数据,并部署在云服务器上。系统前端主要由四个页面组成:登录页、博客列表页、博客详情页和博客编辑页,整体模拟实现了一个简洁的个人博客平台。

已实现的主要功能包括:

  • 用户登录与注销
  • 博客的发布与删除
  • 博客列表与详情查看
  • 强制登录验证(未登录状态下无法访问其他页面)

当前系统存在的不足:

  • 未实现用户注册功能,用户信息需提前写入数据库
  • 用户头像为静态图片,无法自定义设置
  • 用户文章数与分类数未在后端动态统计,前端为静态展示

项目的系统功能说明

1. 登录功能

  • 用户需输入已存在于数据库中的用户名和密码进行登录
  • 登录成功后跳转至博客列表页
  • 未登录状态下点击“主页”或“写博客”按钮,将强制跳转至登录页

2. 博客列表页

  • 展示博客的简要信息,包括标题、发布时间、内容概要
  • 左侧显示当前登录用户的基本信息(如用户名、文章数、分类数等)
  • 右上角提供三个功能按钮:
    • 主页:返回博客列表页
    • 写博客:跳转至博客编辑页
    • 注销:退出当前用户,返回登录页

3. 博客详情页

  • 点击列表页中的“查看全文”按钮进入详情页
  • 展示博客的完整内容,包括标题、发布时间、作者及正文
  • 右上角提供四个功能按钮:
    • 主页:返回博客列表页
    • 写博客:跳转至博客编辑页
    • 删除:删除当前博客,删除后返回列表页
    • 注销:退出当前用户,返回登录页

4. 博客编辑页

  • 登录状态下点击“写博客”按钮进入编辑页
  • 用户可输入博客标题与正文内容
  • 点击“发布文章”按钮后,博客将被保存并发布,随后跳转至博客列表页

测试目标:

  • 目标:主页面测试率达到 90%

测试项目相关信息:

  • 项目链接地址:http://47.94.167.83:8080/blog_login.html
  • 项目代码:https://gitee.com/gu-ling-c-language/spring_-blog
  • 接口:登录,主页,编辑,详情页

测试安排:

模块子模块前端开发提测时间测试工时排期进度备注
登陆登陆功能AileenAileen6.30Aileen0.5d6.31测试完成
主页博主信息、博客列表页、导航栏AileenAileen6.30Aileen0.5d6.31测试完成
写博客博客编辑与发布AileenAileen6.31Aileen1d7.3测试完成
博客详情页博客详情页AileenAileen6.31Aileen0.5d7.3测试完成

测试分类:

(1)功能测试

我的博文项目测试

  • 功能测试结果:测试用例 100%通过

(2)自动化测试

①编写Web测试用例:

②创建空项目

(1)配置准备:添加需要的pom.xml依赖

<dependency><groupId>io.github.bonigarcia</groupId><artifactId>webdrivermanager</artifactId><version>5.8.0</version><scope>test</scope>
</dependency><dependency><groupId>org.seleniumhq.selenium</groupId><artifactId>selenium-java</artifactId><version>4.0.0</version>
</dependency><dependency><groupId>commons-io</groupId><artifactId>commons-io</artifactId><version>2.6</version>
</dependency>

(2)创建驱动对象driver

  • 为了方便测试所有的页面,我们创建一个driver对象供所有的测试用例使用

(3)测试用例的划分

  • 按照页面分类,每个页面就是一个Java文件,页面下所有的用例统一管理

在这里插入图片描述

自动化测试工具准备:

package common;import io.github.bonigarcia.wdm.WebDriverManager;
import org.apache.commons.io.FileUtils;
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 java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;public class Utils {//创建WebDriver对象public static WebDriver driver;public static WebDriver createDriver(){//先判断驱动是否为nullif(driver == null) {//如果为null,则创建一个新的WebDriver实例WebDriverManager.chromedriver().setup();ChromeOptions options = new ChromeOptions();// 允许访问所有网站options.addArguments("--allow-remote-origins=*");//创建ChromeDriver实例driver = new ChromeDriver(options);//等待->隐式等待driver.manage().timeouts().implicitlyWait(java.time.Duration.ofSeconds(2));}return driver;}public Utils(String url){//调用 driver 对象driver = createDriver();//访问urldriver.get(url);}//测试截图public void getScreenShot(String str) throws IOException {//截图放置的位置:  ./src/test/image///                              /2025-7-20///                                        /test01-150001.png//                                        /test02-150030.png//                              /2025-7-21///                                        /test01-150001.png//                                        /test02-150030.png//格式设置SimpleDateFormat sim1 = new SimpleDateFormat("yyyy-MM-dd");SimpleDateFormat sim2 = new SimpleDateFormat("HHmmssSS");//SS将文件名精确到毫秒级别避免截图同名String dirTime = sim1.format(System.currentTimeMillis());String fileTime = sim2.format(System.currentTimeMillis());// ./src/test/image/2025-7-20/test01-150001.pngString filename = "./src/test/image/"+ dirTime +"/"+str +"-"+ fileTime+".png";//打印一下生成的filename名称System.out.println("filename: "+ filename);//屏幕截图File srcFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);//srcFile放到指定位置FileUtils.copyFile(srcFile , new File(filename));}}
  • 后面测试用例就可以通过继承这个工具创建测试对象,访问URL

测试用例tests的编写:

①登录页面:

  • 登录页面的基本功能测试:只有账号和密码匹配才能正常登录,其他情况都登录失败。

检查页面的正常加载:

package tests;import common.Utils;
import org.openqa.selenium.By;public class LoginPage extends Utils {public static String url = "http://47.94.167.83:8080/blog_login.html";/*** 构造函数,调用父类Utils的构造函数* 访问登录页面*/public LoginPage() {super(url);}/***检查页面是否能正确加载* @throws InterruptedException*/public void loginPageRight() throws InterruptedException {//查看页面元素是否存在来检查页面是否能成功加载//这里选择主页按钮元素driver.findElement(By.cssSelector("body > div.nav > a:nth-child(4)"));//登录输入框driver.findElement(By.cssSelector("body > div.container-login > div"));Thread.sleep(3000);driver.quit();}
}

检查成功登录:
    /*** 检查登录功能 - 成功登录*/public void LoginSuc(){//找到登录页面中的用户输入框,输入账号和密码并点击登录按钮driver.findElement(By.cssSelector("#username")).sendKeys("Aileen");driver.findElement(By.cssSelector("#password")).sendKeys("123456");driver.findElement(By.cssSelector("#submit")).click();//检查登录之后是否登陆成功//检查页面是否跳转到博客列表页//根据博客列表页的元素来判断driver.findElement(By.cssSelector("body > div.container > div.right > div:nth-child(1) > a"));//检查页面标题是否正确--这里需要配置断言String exceptTitle = driver.getTitle();assert exceptTitle.equals("博客列表页") : "登录失败,页面标题不正确!";driver.quit();}


检查登录失败:

  • 当我们登录成功之后通过 navigate.back() 回到登录页之后,需要先将账号密码清空才能进行登录失败的测试,否则会叠加到原来成功登录输入的内容之后:
    /*** 检查登录功能 - 登录失败*///检查登录失败,在测完登录成功之后需要先回到登录页面才能进行登录失败的检查↑public void LoginFail() throws InterruptedException {//先清空之前成功登录在输入框中输入的内容://清空方式有两种://1.使用clear()方法driver.findElement(By.cssSelector("#username")).clear();driver.findElement(By.cssSelector("#password")).clear();//2.使用refresh()方法刷新页面//driver.navigate().refresh();//输入错误的账号和密码driver.findElement(By.cssSelector("#username")).sendKeys("Aileen111");//账号错误driver.findElement(By.cssSelector("#password")).sendKeys("123456");driver.findElement(By.cssSelector("#submit")).click();//等待alert弹窗出现Thread.sleep(2000); // 等待2秒钟,确保alert弹窗出现//获取失败的弹窗内容,将它和预期的错误信息进行比较String alertText = driver.switchTo().alert().getText();String expectedAlertText = "用户不存在";assert alertText.equals(expectedAlertText);//接受弹窗driver.switchTo().alert().accept();driver.quit();}

②列表页面测试:

  • 测试列表页面又分为两种情况:登录成功和登录失败(未登录状态)去访问博客列表页:
package tests;import common.Utils;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;import java.io.IOException;public class ListPage extends Utils {public static String url = "http://127.0.0.1:8080/blog_list.html";public ListPage() {super(url);}/*** 根据登录状态访问列表页* 这里需要先登录成功* 测试看列表页是否有只属于列表页的元素* 有则说明访问成功*/public void ListByLogin(){//查看是否能加载列表页String exceptTitle = driver.getTitle();assert exceptTitle.equals("博客列表页") : "列表页加载失败,页面标题不正确!";//查看页面元素是否存在来检查页面是否能成功加载//这里选择查看全文按钮WebElement ele = driver.findElement(By.cssSelector("body > div.container > div.right > div:nth-child(1) > a"));//通过断言检查是否有这个按钮assert ele.isDisplayed() : "列表页加载失败,页面元素不存在!";//点击查看全文按钮ele.click();}
}

  • 未登录状态查看博客列表处理弹窗出现问题
    • 我通过给每个测试用例屏幕截图查找问题

  • 通过截图我们可以看到:我们执行到我们本来预期是:以未登录状态访问列表页的,但是当它执行并跳转到未登录访问博客列表的测试方法前,它通过 driver 访问博客列表时,还保存着之前的登录状态,所以未登录的方法的警告框实际上并未出现。

③编辑页面:

package tests;import common.Utils;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;/*** 特殊测试:编辑页面* 由于markdown是第三方库,无法直接测试博客的发布功能,但是默认情况下页面编辑已有默认内容,* 但是我们可以测试编辑页面的标题,因为标题是我自己实现的HTML元素*/
public class EditPage extends Utils {public static String url = "http://127.0.0.1:8080/blog_edit.html";public EditPage() {super(url);}/*** 发布博客测试* 无法输入博客内容怎么解决----->两种方式*/public void EditSuc() throws InterruptedException {//①方式1:博客本身就有默认内容,无需手动实现WebElement ele = driver.findElement(By.cssSelector("#title"));Thread.sleep(6000); //等待2秒钟,查看输入的效果ele.sendKeys("乌萨奇的博客");Thread.sleep(2000); //等待2秒钟,查看输入的效果driver.findElement(By.cssSelector("#submit")).click();//------------//点击弹窗的确认按钮->跳转到博客列表页Thread.sleep(1000);driver.switchTo().alert().accept();//②方式2:通过鼠标操作来实现---这里就不实现了,有点麻烦...//检查博客发布之后是否成功在列表页展示出WebElement exceptArticleTitle = driver.findElement(By.cssSelector("body > div.container > div.right > div:nth-child(1) > div.title"));String exceptTitle = exceptArticleTitle.getText();assert exceptTitle.equals("乌萨奇的博客") : "编辑页面发布博客失败,标题不正确!";}
}

④:详情页面:

package tests;import common.Utils;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;public class DetailPage extends Utils {public static String url = "http://127.0.0.1:8080/blog_detail.html?blogId=14";public DetailPage() {super(url);}/*** 检查详情页是否能正确加载* 通过查找博客标题元素来判断* @throws InterruptedException*/public void DetailByLogin() throws InterruptedException {//查看页面元素是否存在来检查页面是否能成功加载//这里选择编辑按钮//用户点击编辑,然后修改标题,点击发布,跳转到博客列表页String exceptDetailTitle = driver.getTitle();assert exceptDetailTitle.equals("博客详情页") : "详情页加载失败,页面标题不正确!";Thread.sleep(3000);//点击编辑按钮driver.findElement(By.cssSelector("body > div.container > div.right > div > div.operating > button:nth-child(1)")).click();Thread.sleep(3000);//修改标题WebElement ele = driver.findElement(By.cssSelector("#title"));Thread.sleep(2000); //等待2秒钟,查看输入的效果ele.clear();Thread.sleep(2000); //等待2秒钟,查看输入的效果ele.sendKeys("永不言弃的Aileen");Thread.sleep(2000); //等待2秒钟,查看输入的效果driver.findElement(By.cssSelector("#submit")).click();//将内容发表->点击发布成功弹窗的按钮Thread.sleep(2000);driver.switchTo().alert().accept(); //点击弹窗的确认按钮->跳转到博客列表页Thread.sleep(2000);// 跳转到博客列表页//检查是否跳转到博客列表页String exceptTitle = driver.getTitle();assert exceptTitle.equals("博客列表页") : "详情页修改失败,无法跳转到博客列表页!";//注销按钮测试//点击注销按钮driver.findElement(By.cssSelector("body > div.nav > a:nth-child(6)")).click();Thread.sleep(3000);//检查是否能跳转到登录页面String exceptLoginTitle = driver.getTitle();assert exceptLoginTitle.equals("博客登陆页") : "注销失败,无法跳转到登录页面!";}
}

(3)性能测试:

模拟并发访问登录页面:

  • 2s 内 10 个虚拟用户不断发送请求,总共发送了 4445 次请求

  • 我们可以看到响应时间和吞吐量成反比:
    • 响应时间长,吞吐量小或相对稳定,可能系统达到了性能瓶颈。
    • 响应时间短,吞吐量大,性能越好

  • 根据线程响应时间图,我们可以看到,存在一个异常:有一个线程一直没有退出,下面我们结合聚合报告进一步分析:

- 我们可以考到列表页的响应时间是最长的,说明可能是列表页存在问题,我觉得是因为我们每次列表页返回的都是所有的数据,响应量大,数据较多,导致时间较长
- **解决方案:将返回的响应量分解,给博客列表页添加分页,限制每页返回的最大博客条数,这样就可以有效解决响应时间过长的问题。**

  • 通过 JMeter 生成测试报告,可看到总共 959 个请求,没有错误,错误率为 0,说明高并发场景下,系统能够正常处理业务。
  • 但是博客列表页的响应时间太长了,应该是一次请求的响应资源太多了,我们可以将一次请求的请求量分多次请求来减少响应时间,通过给列表页添加翻页功能,限制每页展示的博客条数

总结测试 tips:

  • 先测试部分接口功能是否能正常实现,再进行整体测试,要注意各个接口之间的关联关系。

](https://img-home.csdnimg.cn/images/20220524100510.png#pic_center)
](https://img-home.csdnimg.cn/images/20220524100510.png#pic_center)

http://www.dtcms.com/a/272127.html

相关文章:

  • 在指定conda 环境里安装 jupyter 和 python kernel的方法
  • 【LeetCode 热题 100】2. 两数相加——(解法二)迭代法
  • MyBatis-Plus 中使用 Wrapper 自定义 SQL
  • 专题:2025供应链数智化与效率提升报告|附100+份报告PDF、原数据表汇总下载
  • 【2025/07/10】GitHub 今日热门项目
  • JavaEE——线程池
  • 嵌入式开发:云端仿真赋能WS2812创意灯光教学
  • PyTorch随机擦除:提升模型抗遮挡能力
  • 【会员专享数据】2013-2024年我国省市县三级逐日SO₂数值数据(Shp/Excel格式)
  • Houdini 分布式解算效率瓶颈突破:渲染 101 云集群实战指南
  • Transformer江湖录 第一章:江湖前传 - 神经网络门派纷争
  • 微服务架构下某汽车APP电商模块订单服务自动化测试方案(Python蹭个场)
  • YOLO11 目标检测从安装到实战
  • [论文阅读]LLMZip: Lossless Text Compression using Large Language Models
  • qemu vcpu的创建过程
  • 智慧气象新范式:人工智能如何重构城市级气象服务生态?
  • AI技术通过智能缺陷检测正在深度重构多个行业的生产模式、质量管理体系和人才结构,其影响已超越单纯的技术升级,正在引发系统性变革。
  • Windows 11 安装过程中跳过微软账户创建本地账户
  • 大模型 Agent(智能体)技术简介
  • 静默的田野革命—人工智能重构农业生态的技术风暴与文明悖论
  • 蛋白质序列-omega参数计算算法解读
  • 「按键精灵安卓/ios辅助工具」动态验证码该怎么得到完整的图片
  • 20250710解决KickPi的K7的SDK编译异常:rk3576-android14.0-25250704.tar.gz【降低BUILD_JOBS】
  • 微软365 PDF导出功能存在本地文件包含漏洞,可泄露敏感服务器数据
  • 【办公类-107-01】20250710视频慢速与视频截图
  • 用 ngrok + SSH 实现公网远程控制电脑
  • Linux Vim 编辑器详解:从入门到进阶(含图示+插件推荐)
  • FPGA设计思想与验证方法系列学习笔记001
  • XCZU47DR-2FFVG1517I Xilinx FPGA AMD ZynqUltraScale+ RFSoC
  • 原生微信小程序研发,如何对图片进行统一管理?