基于博客系统的功能测试和性能测试

news2025/5/26 11:09:52

目录

项目介绍

项目功能

设计测试用例

功能测试--自动化测试

测试代码

登录测试

博客详情页测试

发布博客测试

删除博客测试

退出账号测试

性能测试


项目介绍


1.博客系统采用前后端分离的方法来实现,同时使用了数据库来存储相关的数据,同时将其部署到云服务器上。

2.前端主要有四个页面构成:登录页、列表页、详情页以及编辑页,以上模拟实现了最简单的个人博客系统。其结合后端实现了以下的主要功能:登录、编辑博客、注销、删除博客。

3.博客系统可以实现个人用户简单的博客记录,时间、标题、内容以及发布者等都可以进行详细地查看。

使用JUnit测试框架对博客系统进行功能测试。

项目功能


博客系统主要实现了以下几个功能:登录、注销、写博客以及删除博客等功能。

登录功能:用户名以及密码是已经存在于数据库中的。登录成功后就会跳转到列表页面。在右上角存在主页和写博客两个按钮,但是在未登录情况下按下均只会跳转到登录页面。


列表页面:可以在列表页查看博客简介,其包括博客标题、发布时间以及内容概要。在左侧可以看到登录的用户以及文章数、分类数等的模块。在右上角有主页、写博客和注销三个功能:主页即列表页,写博客即博客编辑页,注销即注销用户,回到登录页面。


详情页面:在列表页面点击“查看全文”按钮就会跳转到详情页,此时就可以看到该篇博客的完整内容。在右上角同样有主页、写博客、删除和注销四个功能。


博客编辑页:在登录之后的任意界面点击“写博客”之后就会进入博客编辑页面,此时就可以进行博客的编写,点击“发布文章”后就可以成功发布文章,此时就会跳转到列表页。

设计测试用例

功能测试--自动化测试

测试代码

先指定在所有测试方法执行之前和所有方法执行之后的要执行的方法。

在所有测试方法前要执行的是登录博客网址,所有测试方法后要执行的是关闭该网页。

public class InitAndEndBrowser {

    /**
     * 打开博客网站
     */
    @BeforeAll
    static void SetUp() {
        // 打开网页,博客列表的登录网址
        webDriver.get("http://xxxxxxxxxx/blog_login.html");
    }

    /**
     * 退出浏览器
     */
    @AfterAll
    static void TearDown() {
        try {
            // 休眠3秒
            sleep(3000);
            // 退出浏览器
            webDriver.quit();
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }
}

登录测试

输入账号和密码,若登录成功,进入博客列表页,博客列表页有注销按钮。出现注销按钮即可说明登录成功。

 /**
     * 账号正确,密码正确登陆成功
     */
    @Order(1)
    @ParameterizedTest
    @CsvSource(value = {"admin, 123456"})
    void Login(String user_name, String passport) throws InterruptedException {
        // 输入账号
        webDriver.findElement(By.cssSelector("#username")).sendKeys(user_name);
        // 输入密码
        webDriver.findElement(By.cssSelector("#password")).sendKeys(passport);
        // 点击登录按钮
        webDriver.findElement(By.cssSelector("#submit")).click();
        sleep(3000);
        // 如果页面出现注销按钮,此时说明登录成功
        WebElement logout_button = webDriver.findElement(By.cssSelector("body > div.nav > a:nth-child(6)"));
        Assertions.assertNotNull(logout_button);
    }

博客详情页测试

/**
     * 点击查看全文,成功跳转到博客详情页面
     */
    @Order(2)
    @ParameterizedTest
    @ValueSource(strings = {"http://xxxxxxxxx/blog_system/blog_detail.html?blogId="})
    void BlogListToBlogInfo(String expected_url) throws InterruptedException {
        // 找到查看全文按钮(这里找到的是全部的查看全文按钮)
        List<WebElement> review_all_blog_buttons = webDriver.findElements(By.xpath("//a[text()=\'查看全文 >>\']"));
        // 点击第一个查看全文按钮
        review_all_blog_buttons.get(0).click();
        // 预期的url是http://42.192.83.143:8563/blog_system/blog_detail.html?blogId=xxx
        String actual_url = webDriver.getCurrentUrl();
        // 判断url是否是详情页url
        if(actual_url.contains(expected_url)) {
            System.out.println("测试通过,当前博客详情页地址是:" + actual_url);
        } else {
            System.out.println("测试不通过,当前页面地址是:" + actual_url);
        }
        sleep(3000);
    }

发布博客测试

发布成功一条博客后会跳转到博客列表页面,检查博客列表页的第一条博客的标题是否和测试的博客标题一致即可。

 /**
     * 发布博客成功,跳转到博客列表页面
     */
    @Order(3)
    @ParameterizedTest
    @CsvFileSource(resources = "test04.csv")
    void EditBlogSimple( String expected_url) throws InterruptedException {
        // 找到发布博客按钮,点击
        webDriver.findElement(By.cssSelector("body > div.nav > a:nth-child(5)")).click();
        // 找到标题输入框,输入"自动化代码发布博客"
        ((JavascriptExecutor)webDriver).executeScript("document.getElementById(\"title\").value='自动化测试代码发布博客'");
        sleep(3000);
        webDriver.findElement(By.cssSelector("#submit")).click();
        // 校验页面是不是跳转到博客列表页面
        // 比较当前页面url是不是等于http://xxxxxxxx/blog_system/blog_list.html
        // 如果相等,跳转页面正确
        // 跳转页面不正确,测试不通过
        String actual_url = webDriver.getCurrentUrl();
        Assertions.assertEquals(expected_url, actual_url);
    }

/**
     * 检查博客列表中第一条博客标题是不是和自己发布的博客标题相等
     */

    public static Stream<Arguments> GeneratorBlogTitle() {
        return Stream.of(Arguments.arguments("#这个是自动化代码写的文章\n"));
    }
    @ParameterizedTest
    @MethodSource("GeneratorBlogTitle")
    @Order(4)
    void CheckBlogTitle(String expected_blog_title) throws InterruptedException {
        sleep(3000);
        // 获取刚才代码发布的博客标题
        String release_blog_title = webDriver.findElement(By.xpath("/html/body/div[2]/div[2]/div[1]/div[3]")).getText();
        // 校验发布的博客标题,是不是和EditBlogSimple方法中发布的博客标题一样
        Assertions.assertNotEquals(expected_blog_title, release_blog_title);
    }

删除博客测试

 /**
     * 删除博客
     */
    @Order(5)
    @Test
    void DeleteBlog() {
        try {
            // 点击查看全文
            sleep(3000);
            webDriver.findElement(By.xpath("/html/body/div[2]/div[2]/div[1]/a")).click();
            sleep(3000);
            // 点击删除按钮
            webDriver.findElement(By.cssSelector("body > div.nav > a:nth-child(7)")).click();
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }

退出账号测试

退出账号后,成功的标志是用户名和密码为空。

/***
     * 退出
     */
    @Order(6)
    @Test
    void Logout() throws InterruptedException{
        // 退出账号
        webDriver.findElement(By.cssSelector("body > div.nav > a:nth-child(6)")).click();
        sleep(3000);
        // 获取用户名信息
        String user_name = webDriver.findElement(By.cssSelector("#username")).getText();
        // 获取密码信息
        String pass_port = webDriver.findElement(By.cssSelector("#password")).getText();
        // 退出后,用户名为空,测试通过,否则测试不通过
        Assertions.assertEquals("", user_name);
        // 退出后,密码为空,测试通过,否则测试不通过
        Assertions.assertEquals("", pass_port);
    }

以上,可以保证博客系统的基本功能正常。

性能测试

使用loadRunner进行简单性能测试:针对登录、编写并发布博客以及删除博客、注销等功能进行简单的性能测试。
然后在实现的过程中,插入集合点以及事务等,并通过设置来实现用户的并发操作。

对登录进行测试:

1.添加访问地址

2.通过开发者工具查看请求发送的格式,以此来进行性能测试脚本的编写

3.用户名以及密码可以有多个,可以进行参数化。

4.添加事务以及集合点、检查点:注意检查点一般放在请求之前。

5.设置迭代次数:为了能够更好地遍历到所有的参数。

6.脚本测试

7.设置并发数量进行性能测试,并导出测试报告以及图表
(1)设置10个虚拟用户

(2)在Controller中设置场景

(3)开始进行运行,性能测试(运行中和结束的截图)

(4)在Analysis中查看性能报告以及报表
① 报告

② 点击率

③ 吞吐量

④ 系统资源

分析系统资源:击率较大时,CPU利用率较高,这就是系统可以优化的一个方向。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1593074.html

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

相关文章

Vue - 5( 16000 字 Vue2 入门级教程)

一&#xff1a;Vue 初阶 1.1 组件自定义事件 在 Vue 中&#xff0c;组件间通过自定义事件进行通信是一种常见的模式。自定义事件允许子组件向父组件发送消息&#xff0c;也可以在组件内部进行事件的绑定、触发和解绑。让我们详细讲解这些知识点。 1.1.1 组件自定义事件 在 …

CSS核心样式-02-盒模型属性及扩展应用

目录 三、盒模型属性 常见盒模型区域 盒模型图 盒模型五大属性 1. 宽度 width 2. 高度 height 3. 内边距 padding 四值法 三值法 二值法 单值法 案例 4. 边框 border 按照属性值的类型划分为三个单一属性 ①线宽 border-width ②线型 border-style ③边框颜色 bo…

开源项目one-api的k8s容器化部署(下)-- 部署至k8s

一、接着上文 本文讲述如何把上文制作好的docker镜像部署到K8S&#xff0c;会涉及以下部分&#xff1a; 健康检测应用程序的配置应用程序的端口日志路径 二、健康检测 1、健康状态 从官方的docker-compose.yml可以得知其健康检测方法 curl http://localhost:5175/api/statu…

正则表达式:特殊序列(五)

正则表达式中的特殊序列包括&#xff1a;1. \d&#xff1a;匹配任意数字字符&#xff0c;等同于[0-9]。2. \D&#xff1a;匹配任意非数字字符&#xff0c;等同于[^0-9]。3. \w&#xff1a;匹配任意字母、数字或下划线字符&#xff0c;等同于[A-Za-z0-9_]。4. \W&#xff1a;匹配…

电路知识分享

电路 1. 基尔霍夫 KCL 定律 基尔霍夫定律包括电流定律和电压定律 电流定律KCL&#xff1a;在电路中&#xff0c;任何时刻&#xff0c;对任一节点&#xff0c;所有流出节点的支路电流的代数和恒等于零。 电压定律KVL&#xff1a;在集总电路中&#xff0c;任何时刻&#xff0…

3D场景编辑方法——CustomNeRF

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 摘要Abstract文献阅读&#xff1a;3D场景编辑方法——CustomNeRF1、研究背景2、提出方法3、CustomNeRF3.1、整体框架步骤3.2、对特定问题的解决 4、实验结果5、总结…

支持向量机模型

通过5个条件判定一件事情是否会发生&#xff0c;5个条件对这件事情是否发生的影响力不同&#xff0c;计算每个条件对这件事情发生的影响力多大&#xff0c;写一个支持向量机模型程序,最后打印5个条件分别的影响力。 示例一 为了计算每个条件对一件事情发生的影响力&#xff0c…

年龄与疾病c++

题目描述 某医院想统计一下某项疾病的获得与否与年龄是否有关&#xff0c;需要对以前的诊断记录进行整理&#xff0c;按照0-18岁、19-35岁、36-60岁、61以上&#xff08;含61&#xff09;四个年龄段统计的患病人数以及占总患病人数的比例。 输入 共2行&#xff0c;第一行为过…

JavaSE——常用API进阶二(3/8)-Date、SimpleDateFormat(构造器、常用的方法、用法示例、时间格式的常见符号)

目录 Date 构造器、常用的方法 用法示例 SimpleDateFormat 构造器、格式化时间的方法 时间格式的常见符号 用法示例 解析字符串时间成为日期对象 接下来会学习JDK8以前传统的日期、时间&#xff0c;以及JDK8开始新增的日期、时间&#xff1b;有部分项目还是有在使用JDK…

雷霆传奇H5_源码搭建架设_神魔之魔改龙珠2

本教程仅限学习使用&#xff0c;禁止商用&#xff0c;一切后果与本人无关&#xff0c;此声明具有法律效应&#xff01;&#xff01;&#xff01;&#xff01; 一. 效果演示 雷霆传奇H5_源码搭建架设_神魔之魔改龙珠2 联网环境&#xff1a; centos7.6 &#xff0c; 放开所有端口…

数据治理专家岗位的能力模型

数据治理专家的角色要求其具备全方位的专业素养与技能&#xff0c;不仅要有深厚的业务理解与数据技术功底&#xff0c;还需展现出卓越的领导力、团队协作与沟通能力&#xff0c;以驱动组织内部数据治理工作的高效运行与持续优化。以下是对数据治理专家各项能力的深入解读&#…

算法题 - 双指针

目录 125. 验证回文串392. 判断子序列167. 两数之和 Ⅱ - 输入有序数组11. 盛最多的水15. 三数之和 125. 验证回文串 LeetCode_link 如果在将所有大写字符转换为小写字符、并移除所有非字母数字字符之后&#xff0c;短语正着读和反着读都一样。则可以认为该短语是一个 回文串 …

【问题篇】activiti工作流流程图更新后旧数据问题

互相学习交流 当我们使用activiti开发工作流时&#xff0c;项目上线后可能修改需求导致修改流程图也是很常见的情况。但是activiti更新流程图后&#xff0c;以前的流程实例并不会也跟着更新&#xff0c;activiti会保存每一份的流程图版本&#xff0c;只有新发起的流程实例才会…

架构设计-权限系统之通用的权限系统设计方案

一个系统&#xff0c;如果没有安全控制&#xff0c;是十分危险的&#xff0c;一般安全控制包括身份认证和权限管理。用户访问时&#xff0c;首先需要查看此用户是否是合法用户&#xff0c;然后检查此用户可以对那些资源进行何种操作&#xff0c;最终做到安全访问。身份认证的方…

spring boot集成logback到mysql 8

spring boot集成logback到mysql 8 依赖数据库准备创建log日志用户&#xff0c;并创建数据库执行建表sql 配置文件bugbug 1&#xff1a;Failed to instantiate type ch.qos.logback.classic.db.DBAppenderbug信息&#xff1a;解决&#xff1a; bug2: DBAppender cannot function…

开源博客项目Blog .NET Core源码学习(14:App.Hosting项目结构分析-2)

开源博客项目Blog的前台页面&#xff08;如下图所示&#xff09;的控制器类保存在App.Hosting项目的Controllers文件夹内&#xff0c;页面保存在Views文件夹内&#xff0c;网页中使用的图标、js、css文件等保存在wwwroot文件中。 前台各个页面、Controller文件夹中的控制器类及…

上位机图像处理和嵌入式模块部署(镜头和相机的选择)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 在机器视觉当中&#xff0c;除了光源比较重要之外&#xff0c;另外最最重要的就是镜头和相机的选择了。通常来说&#xff0c;镜头是机械和光学装置…

【算法】分治-快排

个人主页 &#xff1a; zxctscl 如有转载请先通知 题目 前言1. 75. 颜色分类1.1 分析1.2 代码 2. 912. 排序数组2.1 分析2.2 代码 3. 215. 数组中的第K个最大元素3.1 分析3.2 代码 4. LCR 159. 库存管理 III4.1 分析4.2 代码 前言 分治就是分而治之 1. 75. 颜色分类 1.1 分析…

解决vue3更新chunk包后,点击页面报错

出现错误 解决思路 试了好多方法&#xff0c;跳了很多坑&#xff0c;router版本对不上&#xff0c;解决方案不实用。最后我直接捕获异常&#xff0c;刷新页面&#xff0c;解决最快最有效。 // vue-rotuer版本 "vue-router": "^4.0.3"解决方案 在router/…

(学习日记)2024.04.18:UCOSIII第四十六节:CPU利用率及栈检测统计

写在前面&#xff1a; 由于时间的不足与学习的碎片化&#xff0c;写博客变得有些奢侈。 但是对于记录学习&#xff08;忘了以后能快速复习&#xff09;的渴望一天天变得强烈。 既然如此 不如以天为单位&#xff0c;以时间为顺序&#xff0c;仅仅将博客当做一个知识学习的目录&a…