博客系统--测试报告

news2025/4/3 15:22:01

博客系统--测试报告

  • 项目背景
  • 项目功能
  • 功能测试
    • ①登录功能测试
    • ②发布博客功能测试
    • ③删除文章功能测试
    • ④功能测试总结:
  • 自动化测试
    • 自动化脚本执行界面:
  • 性能测试

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

项目背景

博客系统采用前后端不分离的方法来实现,同时使用了数据库来存储相关的数据,且已将其部署到云服务器上。前端主要有五个页面构成:登录页,文章列表页,文章详情页,文章编辑(修改)页和文章发布页。以上模拟实现了最简单的博客系统。其实现了以下的主要功能:登录、新增文章、对自己文章的删改查、查看他人文章、注销登录并使用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)"));
        //查看url
        String 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.coloradmin.cn/o/2309139.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【博资考4】网安学院-硕转博考试内容

【博资考4】硕转博考试内容 - 网络安全与基础理论 写在最前面一. **21年硕转博面试内容回顾**网络、逆向、操作系统、攻防、漏洞1. **网络安全常见攻击方式及其防范措施**1.1 **DDoS攻击(分布式拒绝服务)**1.2 **SQL注入攻击**1.3 **XSS攻击(…

GPT-4.5 怎么样?如何升级使用ChatGPTPlus/Pro? GPT-4.5设计目标是成为一款非推理型模型的巅峰之作

GPT-4.5 怎么样?如何升级使用ChatGPTPlus/Pro? GPT-4.5设计目标是成为一款非推理型模型的巅峰之作 今天我们来说说上午发布的GPT-4.5,接下来我们说说GPT4.5到底如何,有哪些功能?有哪些性能提升?怎么快速使用到GPT-4.…

基于专利合作地址匹配的数据构建区域协同矩阵

文章目录 地区地址提取完成的处理代码 在专利合作申请表中,有多家公司合作申请。在专利权人地址中, 有多个公司的地址信息。故想利用这里多个地址。想用这里的地址来代表区域之间的专利合作情况代表区域之间的协同、协作情况。 下图是专利合作表的一部分…

0x02 js、Vue、Ajax

文章目录 js核心概念js脚本引入html的方式基础语法事件监听 Vuevue简介v-forv-bindv-if&v-showv-model&v-on Ajax js 核心概念 JavaScript:是一门跨平台、面向对象的脚本语言,用来控制网页行为实现交互效果,由ECMAScript、BOM、DOM…

IDEA 使用codeGPT+deepseek

一、环境准备 1、IDEA 版本要求 安装之前确保 IDEA 处于 2023.x 及以上的较新版本。 2、Python 环境 安装 Python 3.8 或更高版本 为了确保 DeepSeek 助手能够顺利运行,您需要在操作系统中预先配置 Python 环境。具体来说,您需要安装 Python 3.8 或更高…

Linux笔记---一切皆文件

1. 含义 “一切皆文件”是 Linux 对系统资源的高度抽象,通过文件接口屏蔽底层差异,提供了简洁、一致的操作方式。这种设计降低了系统复杂性,使得工具、脚本和应用程序能够以统一模式处理多样化资源,是 Linux 强大灵活性的重要基石…

DeepSeek开源周,第五弹再次来袭,3FS

Fire-Flyer 文件系统(3FS)总结: 一、核心特点 3FS 是一个专为 AI 训练和推理工作负载设计的高性能分布式文件系统,利用现代 SSD 和 RDMA 网络,提供共享存储层,简化分布式应用开发。其主要特点包括&#xf…

【音视频】VLC播放器

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 一、vlc是什么? VLC Media Player(简称VLC)是一款免费、开源、跨平台的多媒体播放器,由非营利组织VideoLAN开发,最…

【软件测试】_使用selenium进行自动化测试示例

目录 1. 导入依赖 2. 使用selenium编写测试代码 3. 运行结果 4. 关于浏览器驱动管理及浏览器驱动配置 创建一个空项目用于进行selenium的自动化测试。 1. 导入依赖 <dependencies><!-- https://mvnrepository.com/artifact/io.github.bonigarcia/webdrivermanager…

【清华大学】DeepSeek从入门到精通完整版pdf下载

DeepSeek从入门到精通.pdf 一共104页完整版 下载链接: https://pan.baidu.com/s/1-gnkTTD7EF2i_EKS5sx4vg?pwd1234 提取码: 1234 或 链接&#xff1a;https://pan.quark.cn/s/79118f5ab0fd 一、DeepSeek 概述 背景与定位 DeepSeek 的研发背景 核心功能与技术特点&#xff08…

题解 | 牛客周赛83 Java ABCDEF

目录 题目地址 做题情况 A 题 B 题 C 题 D 题 E 题 F 题 牛客竞赛主页 题目地址 牛客竞赛_ACM/NOI/CSP/CCPC/ICPC算法编程高难度练习赛_牛客竞赛OJ 做题情况 A 题 输出两个不是同一方位的字符中的任意一个就行 import java.io.*; import java.math.*; import java…

C语言(16)---------->二维数组

在学习二维数组之前&#xff0c;掌握一维数组是非常重要的。 对于一维数组的学习&#xff0c;读者可以参考我写过的博客&#xff1a; C语言&#xff08;15&#xff09;--------------&#xff1e;一维数组-CSDN博客 这里面由浅入深地介绍了C语言中一维数组的使用。 一、二维…

【计算机网络基础】-------计算机网络概念

1.什么是计算机网络 定义&#xff1a; 图解&#xff1a; 2.最简单的计算机网络 其中&#xff1a; 结点可以是计算机、集线器、交换机、路由器等链路可以是有线链路、无线链路 2.1集线器 2.2交换机 3.互连网&#xff08;internet&#xff09;与 路由器 路由器 与 家用路由…

C++实现3D(EasyX)详细教程

一、关于3D 我们看见&#xff0c;这两个三角形是相似的&#xff0c;因此计算很简单 若相对物体的方向是斜的&#xff0c;计算三角函数即可 不会的看代码 二、EasyX简介 initgraph(长,宽) 打开绘图 或initgraph(长,宽…

Centos7部署k8s(单master节点安装)

单master节点部署k8s集群(Centos) 一、安装前准备 1、修改主机名 按照资源准备修改即可 # master01 hostnamectl set-hostname master01 ; bash # node1 hostnamectl set-hostname node1 ; bash # node2 hostnamectl set-hostname node2 ; bash2、修改hosts文件 以下命令所…

【C】链式二叉树算法题1 -- 单值二叉树

leetcode链接https://leetcode.cn/problems/univalued-binary-tree/description/ 1 题目描述 如果二叉树每个节点都具有相同的值&#xff0c;那么该二叉树就是单值二叉树。只有给定的树是单值二叉树时&#xff0c;才返回 true&#xff1b;否则返回 false。 示例 1&#xff1…

word转换为pdf后图片失真解决办法、高质量PDF转换方法

1、安装Adobe Acrobat Pro DC 自行安装 2、配置Acrobat PDFMaker &#xff08;1&#xff09;点击word选项卡上的Acrobat插件&#xff0c;&#xff08;2&#xff09;点击“首选项”按钮&#xff0c;&#xff08;3&#xff09;点击“高级配置”按钮&#xff08;4&#xff09;点…

蓝桥杯 灯笼大乱斗【算法赛】

问题描述 元宵佳节&#xff0c;一场别开生面的灯笼大赛热闹非凡。NN 位技艺精湛的灯笼师依次落座&#xff0c;每位师傅都有相应的资历值&#xff0c;其中第 ii 位师傅的资历值为 AiAi​。从左到右&#xff0c;师傅们的资历值逐级递增&#xff08;即 A1<A2<⋯<ANA1​&l…

【多模态大模型学习】位置编码的学习记录

【多模态大模型学习】位置编码的学习记录 0.前言1. sinusoidal编码1.0 数学知识——复数1.0.1 复数乘法、共轭复数1.0.2 复数的指数表示 1.1 sinusoidal编码来历1.2 代码实现 2. Rotary Positional Embedding (RoPE) ——旋转位置编码2.1 RoPE来历2.2 代码实现2.2.1 GPT-J风格的…

vector 面试点总结

ps&#xff1a;部分内容使用“AI”查询 一、入门 1、什么是vector 动态数组容器&#xff0c;支持自动扩容、随机访问和连续内存存储。 2、怎么创建-初始化vector std::vector<int> v; // 创建空vectorstd::vector<int> v {1, 2, 3}; // 直接初始化std::vec…