博客系统--测试报告

ops/2025/3/3 14:56:47/

博客系统--测试报告

本博文主要针对个人实现的项目《博客系统》去进行功能测试、自动化测试、性能测试,并记录总结

项目背景

博客系统采用前后端不分离的方法来实现,同时使用了数据库来存储相关的数据,且已将其部署到云服务器上。前端主要有五个页面构成:登录页,文章列表页,文章详情页,文章编辑(修改)页和文章发布页。以上模拟实现了最简单的博客系统。其实现了以下的主要功能:登录、新增文章、对自己文章的删改查、查看他人文章、注销登录并使用Jwt完成了令牌登录校验等功能。
但该项目没有注册账号,点赞文章,筛选文章等功能,且用户没法自行设置头像

项目功能

该博客系统主要实现了以下几个功能:登录、注销、回到主页(文章列表页)、写文章、修改/删除自己的文章、查看文章详情、且支持MD编辑器。

  • 登录功能:由于没有注册功能,用户名以及密码只能在数据库写死,直接输入给出的用户名和密码登录即可。但是在未登录(如:Token过期)情况下按下点击任意按钮或刷新页面均会跳转到登录页面。
  • 注销功能:用户在任意界面点击右上角“注销”按钮,回到登录页面。
  • 回到主页(文章列表页)功能:用户在任意界面点击右上角“主页”按钮,进入文章列表页。
  • 写博客功能:用户在任意界面点击右上角“写文章”按钮,进入写文章页面。
  • 修改/删除博客功能:用户在查看自己写的文章时会显示“编辑”和“删除”按钮,点击“编辑”按钮会进入编辑页面,点击“更新文章”按钮会提示“修改成功”,再点击“确认”按钮后会自动跳转至文章列表页并展示更新的内容;点击“删除”按钮会提示“删除成功”,再点击“确认”按钮后会自动跳转至文章列表页,且刚才查看的文章已不再展示。
  • 查看博客功能:用户在文章列表页可以看到每篇文章下面都有“查看全文>>”按钮,点击该按钮进入文章详情页,页面包括文章作者信息,文章第一次发布的时间等。

功能测试

①登录功能测试

由于没有实现注册功能,所以我们的用户名和密码都是在数据库里写死的,所以只能用系统原始的数据进行登录

执行步骤: 访问网站-> 输入用户名及密码 ->单击"提交"
在这里插入图片描述
测试过程部分截图:

输入用户名为空::
输入不存在的用户:
在这里插入图片描述

②发布博客功能测试

在这里插入图片描述

不填写标题,发布失败:
在这里插入图片描述

③删除文章功能测试

在这里插入图片描述
从前端看的话,如果我们登录的用户并不是该篇博客的作者,是不会显示 编辑删除 这两个按钮的,但是此处可以进行思维扩展:我们也是可以通过其他工具去向后端发送请求执行删除文章操作的,此处就发现了一处bug
在这里插入图片描述
可以看到此处我们登录的是 lisi 用户,在前端展示和我们预期的一样,隐藏了编辑和删除按钮,但是当我们用Postman进行后端接口测试的时候却发现了问题:
在这里插入图片描述
我们用 lisi 账户登录后所携带的令牌去删除作者是 zhangsan 的博客,后端居然请求成功了,再到数据库里查看数据,发现博客已经被逻辑删除了,这样的情况相当于我拿着自己家的钥匙开了别人家的门,所以此处肯定是不安全的,应该进行代码层面上的逻辑校验
在这里插入图片描述

④功能测试总结:

用户登录测试用例表

用例名称用户登录功能
测试目的测试用户能通过系统给定的的用户名和密码进行登录
测试前提用户处于博客系统登录页
测试流程1)进入登录页面 2)输入事先准备的测试数据(用户名和密码)
预期结果输入正确的用户名和密码时,成功跳转至博客列表页,反之则弹出相应的错误对用户进行提示
实际结果与预期结果基本一致

发布文章测试用例表

用例名称发布文章功能
测试目的测试用户能通过在登陆后进行博客的编写及发布
测试前提用户已登录
测试流程1)登录博客系统 2)进入博文编辑页 3)输入事先准备的测试数据 (博文内容) 4)单击发布博文
预期结果如果输入了标题内容,就能进行发布,反之则发布失败,对用户进行弹窗提示
实际结果与预期结果基本一致,提示信息需要补全

删除文章测试用例表

用例名称删除文章功能
测试目的测试用户在登录后能够删除自己的文章
测试前提用户已登录,并且已经发表该文章
测试流程1)登录博客系统 2)进入个人主页 3)单击查看全文4)单击删除博文 2. 使用postman工具调用删除博文接口
预期结果用户只能对自己的博客进行删除操作
实际结果与预期结果不一致,此处代码逻辑需进行更改

自动化测试

现采用Selenium搭配Junit一些Api对博客系统设计UI自动化测试用例,
主要针对核心功能: 用户登录、博文的查看及删除、用户注销登录 功能进行测试

自动化代码 码云:

由于该项目很早前就部署在服务器上了,并且服务器配置实在过低,会导致我们在进行自动化时有些资源很难加载完全,但经过很多遍测试发现在执行自动化测试的时候只要代码逻辑正确,代码还是能够跑的通的

本次自动化测试主要执行以下逻辑:用户错误登录->用户正确登录->用户发表博客->用户查看博客->用户删除博客用户注销

①前置准备

//工具类封装
public class Utils {public static WebDriver driver;public static WebDriver createDriver(){if (driver == null){//浏览器配置WebDriverManager.edgedriver().setup();EdgeOptions options = new EdgeOptions();//允许访问所有链接options.addArguments("--remote-allow-origins=*");options.setPageLoadStrategy(PageLoadStrategy.NORMAL);driver = new EdgeDriver(options);//设置隐式等待WebDriver.Timeouts wait = driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(5));}return driver;}public Utils(String url){driver = createDriver();driver.get(url);}}
package tests;import common.Utils;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.UnhandledAlertException;import java.io.IOException;
//博客测试
public class BlogTest extends Utils {private static String blog_system = "http://120.26.87.94:8080/blog_list.html";public BlogTest() {super(blog_system);}/*** 失败登录* @throws IOException* @throws UnhandledAlertException* @throws InterruptedException*/public void LoginFail() throws IOException, UnhandledAlertException, InterruptedException {driver.findElement(By.cssSelector("#username")).sendKeys("zhangsan");driver.findElement(By.cssSelector("#password")).sendKeys("1234");driver.findElement(By.cssSelector("#submit")).click();Thread.sleep(2000);String alertText = "";Alert alert = driver.switchTo().alert();alertText = alert.getText();Thread.sleep(2000);alert.accept();assert alertText.equals("密码错误");driver.navigate().refresh();}/*** 成功登录* @throws IOException*/public void LoginSuccess() 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("123456");driver.findElement(By.cssSelector("#submit")).click();//查看注销按钮driver.findElement(By.cssSelector("body > div.nav > a:nth-child(6)"));//查看urlString expect = driver.getTitle();assert expect.equals("博客列表页");}/*** 编辑博客* @throws InterruptedException*/public void EditSuc() throws InterruptedException {driver.findElement(By.cssSelector("body > div.nav > a:nth-child(5)")).click();String blogTitle = "Edit Test";driver.findElement(By.cssSelector("#title")).sendKeys(blogTitle);Thread.sleep(2000);driver.findElement(By.cssSelector("#submit")).click();Thread.sleep(2000);String title = driver.getTitle();assert title.equals("博客列表页");}/*** 查看博客*/public void ViewBlog() throws InterruptedException {driver.findElement(By.cssSelector("body > div.container > div.right > div:nth-child(1) > a")).click();Thread.sleep(2000);}/*** 注销用户*/public void Logout(){driver.findElement(By.cssSelector("body > div.nav > a:nth-child(6)")).click();driver.quit();}/*** 删除博客* @throws InterruptedException*/public void DeleteBlog() throws InterruptedException {driver.findElement(By.cssSelector("body > div.container > div.right > div > div.operating > button:nth-child(2)")).click();Thread.sleep(2000);Alert alert = driver.switchTo().alert();alert.accept();}}

执行我们编写的自动化代码

自动化脚本执行界面:

博客系统自动化测试

性能测试

我们此处使用Jmeter提供的梯度压测功能对博客系统进行压测,由于服务器实在过于脆弱,此处将只设置20个线程数,以及一分钟的持续压测时间,对我们系统的 登录、查询博客列表、查询用户信息、查询作者信息以及添加博客这几个接口进行压测
在这里插入图片描述
配置好线程组之后我们在使用命令提示符,启动我们保存好的 .jmx 格式文件,并将其输出的测试报告文件及日志保存到我们指定的目录
在这里插入图片描述
按回车键执行以后,我们过一会就能在指定目录下查看其生成的性能测试报告了

双击生成的html文件,查看jmeter生成的性能测试报告了
在这里插入图片描述
在这里插入图片描述
可以看到我们发送的很多请求都调用失败了

在这里插入图片描述
可以看到基本都是一种异常

后来翻阅网上资料找到了解决方法:https://javaziliao.com/post/5948.html


http://www.ppmy.cn/ops/162789.html

相关文章

LeetCode 热题100 438. 找到字符串中所有字母异位词

LeetCode 热题100 | 438. 找到字符串中所有字母异位词 大家好,今天我们来解决一道经典的算法题——找到字符串中所有字母异位词。这道题在 LeetCode 上被标记为中等难度,要求我们在字符串 s 中找到所有是 p 的异位词的子串,并返回这些子串的…

Linux(centOS) 命令提示符格式修改(PS1)

1. 命令提示符的组成 命令提示符(PS1)通常由以下部分组成: 部分示例说明[ 和 ][...]提示符的开头和结尾,用于视觉分隔。用户名root 或 tianjiajie当前登录的用户。root 是超级用户,普通用户可能是其他名称。分隔用户…

16.11 LangChain SQL 生成与执行实战:构建安全高效的数据库查询引擎

LangChain SQL 生成与执行实战:构建安全高效的数据库查询引擎 关键词:SQL 安全执行、数据库连接池、查询结果处理、错误重试机制、生产级 SQL 运维 1. SQL 执行全链路架构设计 1.1 核心处理流程图 #mermaid-svg-2aWgNUpLctOECv8J {font-family:"trebuchet ms",ve…

ARM Linux LCD上实时预览摄像头画面

文章目录 1、前言2、环境介绍3、步骤4、应用程序编写4.1、lcd初始化4.2、摄像头初始化4.3、jpeg解码4.4、开启摄像头4.5、完整的程序如下 5、测试5.1、编译应用程序5.2、运行应用程序 6、总结 1、前言 本次应用程序主要针对支持MJPEG格式输出的UVC摄像头。 2、环境介绍 rk35…

react 编写一个待办事项,函数优化,组件传值

待办事项 Import react {component} from ‘react’ Class TodoList extend component{ Costructor(props){ Super(props); This.state{ Value””, List:[] } } getValue(e){ Let valuee.target.value; This.setState({ value }) } addValue(){ This.setState({ List:[...thi…

conda 更换镜像究极方法

conda安装软件一直用的北外镜像,但是我租的服务器机构IP好像最近被屏蔽了,一直无法使用。机构内部搭了本地镜像。 在更换本地镜像(修改.condarc文件)后,新建环境可以正常使用本地镜像,但是之前建的环境依旧…

dify基础之prompts

摘要:在大型语言模型(LLM)应用中,Prompt(提示词)是连接用户意图与模型输出的核心工具。本文从概念、组成、设计原则到实践案例,系统讲解如何通过Prompt解锁LLM的潜能,提升生成内容的…

MAC M1 Pro 安装docker desktop 无法启动

MAC M1 Pro 安装docker desktop 无法启动 今天安装docker desktop,结果反反复复安装了很多遍,总是启动不成功,桌面启动好久然后弹出下图错误: 我先是按照一些解决方案尝试了比如https://dev59.com/mlEG5IYBdhLWcg3wP35V 卸载重…