前言

本篇博客对简易的博客系统做的测试总结一份测试报告,包含功能测试,自动化测试,性能测试

💓 个人主页:zkf

⏩ 文章专栏:测试

若有问题 评论区见📝

🎉欢迎大家点赞👍收藏⭐文章

目录

项目背景

项目概述

已实现的功能

未实现的功能

博客项目系统的功能概括

登录功能

博客列表页

博客详情页

博客编辑页

测试计划

测试用例

测试分类

功能测试

自动化测试

编写自动化测试用例

自动化测试所需工具

自动化测试流程

性能测试

性能测试工具

性能测试流程

性能测试报告

测试总结


项目背景

现如今越来越多的博客平台不断出现,发布博客已成为技术交流与知识分享的重要途径,我在日常写作和交流中也深刻体会到一个高效、便捷、安全的博客系统对于个人成长和技术传播的重要性,所以我认为一个博客系统的开发与测试至关重要。

项目概述

本博客系统项目是一个基于前后端分离架构的系统项目,运用数据库,将博客系统的账户与博客数据存储在云服务器上,前端实现主要由四个页面组成,分别是:登录页、博客列表页、博客详情页和博客编辑页,后端是对应实现的细节操作的接口,从而构成一个简易的博客系统的组成

已实现的功能

用户登录与注销

博客的发布与删除

博客列表与详情查看

用户登录错误的警告弹窗

未实现的功能

没有注册功能,需提前写进数据库

没有统计博客数和用户数

头像只能为静态

删除博客功能未在页面上实现

博客未编写完成时不能保存

博客项目系统的功能概括

登录功能

登录页面有对应的用户名和密码输入框还有对应的提交按钮,输入已存在数据库的用户数据,点击提交,跳转到博客列表页,若未登录下点击右上角主页或写博客,将强制跳转到登录页

博客列表页

该页面展示登录用户的头像与地址,文章个数与分类数,并且展示每篇博客的简要信息(标题,简要内容,发布时间等),右上角注销按钮,退出登录,返回登录页面,主页返回博客列表页,写博客跳转至博客编辑页

博客详情页

点击列表页中的查看详情按钮进入详情页,显示该博客标题,时间,详细内容,右上角三个按钮,效果跟上面一样

博客编辑页

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


测试计划

功能前端开发后端开发提测日期测试测试日期测试结果
登录zkfzkf8.16zkf8.17通过
主页zkfzkf8.16zkf8.17通过
详情页zkfzkf8.17zkf8.18通过
编辑页zkfzkf8.17zkf8.18通过
回归测试zkf8.20通过

测试用例


测试分类

功能测试

一个博客系统的功能测试

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

自动化测试

编写自动化测试用例

自动化测试所需工具

Python集成开发环境:Pycharm

python运行环境:Python 3.9

安装所需要的相关库:selenium,webdriver-manager

自动化测试流程

搭建目录以及相关软件

首先,创建BlogAutoTest测试项目,然后创建两个文件包一个是common,另一个是tests,tests里面存放每个页面的测试文件,common里创建个Utils用于构建浏览器对象,以及用到的截图工具功能,再创建一个images文件存放截到的图片

Utils.py文件

import datetime
import os.path
import sysfrom selenium import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManagerclass Driver:driver=""def __init__(self):options=webdriver.ChromeOptions()self.driver=webdriver.Chrome(service=Service(ChromeDriverManager().install()),options=options)self.driver.implicitly_wait(2)def screePhoto(self):dirname=datetime.datetime.now().strftime("%Y-%m-%d")if not os.path.exists("../images/"+dirname):os.mkdir("../images/"+dirname)filename=sys._getframe().f_back.f_code.co_name+"-"+datetime.datetime.now().strftime("%Y-%m-%d-%H%M%S")+".png"self.driver.save_screenshot("../images/"+dirname+"/"+filename)
BlogDriver=Driver()

创建一个Driver浏览器对象,初始化函数中通过selenium库里对应的webdriver创建Chrome浏览器对象,所需要的服务用到对应的Chrome驱动,对应驱动在webdriver-manager库里,options配置选择默认配置就行,再配置个隐式等待。在类里在创建个截图功能函数,函数里首先通过对应的年月日创建目录名称,在该目录下再用年月日时分秒与对应测试的功能名称创建对应截图文件名,这样子可以防止文件命名冲突并且可以快速查找什么时候哪个功能测试结果图。最后在创建个该类的全局变量,让其他测试文件用一个用例就行


BlogLoginTest.py

import timefrom selenium.webdriver.common.by import By
from common.Utils import BlogDriverclass BlogLogin:url=""driver=""def __init__(self):self.url="http://8.137.19.140:9090/blog_login.html"self.driver=BlogDriver.driverself.driver.get(self.url)#成功登录的出测试用例def LoginSucTest(self):time.sleep(3)self.driver.find_element(By.CSS_SELECTOR, "#username").clear()self.driver.find_element(By.CSS_SELECTOR, "#password").clear()self.driver.find_element(By.CSS_SELECTOR,"#username").send_keys("zhangsan")self.driver.find_element(By.CSS_SELECTOR, "#password").send_keys("123456")self.driver.find_element(By.CSS_SELECTOR, "#submit").click()self.driver.find_element(By.CSS_SELECTOR, "body > div.container > div.left > div > h3")BlogDriver.screePhoto()self.driver.back()#异常登录的测试用例def LoginFauTest(self):self.driver.find_element(By.CSS_SELECTOR, "#username").clear()self.driver.find_element(By.CSS_SELECTOR, "#password").clear()self.driver.find_element(By.CSS_SELECTOR, "#username").send_keys("zhang")self.driver.find_element(By.CSS_SELECTOR, "#password").send_keys("1234")self.driver.find_element(By.CSS_SELECTOR, "#submit").click()time.sleep(2)alert=self.driver.switch_to.alerttime.sleep(2)alert.accept()self.driver.find_element(By.CSS_SELECTOR, "#username").clear()self.driver.find_element(By.CSS_SELECTOR, "#password").clear()BlogDriver.screePhoto()
login=BlogLogin()

点击“检查”

选择要检查的对应目标

选择以选择器方式拷贝对应元素

在编写代码时,在find_element函数里粘贴,来查找对应元素目标,通过send_keys或click进行写入对应元素文本框或点击对应元素

在异场登录弹出的警告框不属于页面内容,需要用switch_to.alert跳转到对应警告框,accept表示接收警告框信息,成功登录与异常登录结果分别截图


BlogListTest.py

from common.Utils import BlogDriver
from selenium.webdriver.common.by import Byclass Bloglist:url=""driver=""def __init__(self):self.driver=BlogDriver.driverself.url="http://8.137.19.140:9090/blog_list.html"self.driver.get(self.url)def testBlogList(self):self.driver.find_element(By.CSS_SELECTOR,"body > div.container > div.right > div:nth-child(1) > a")self.driver.find_element(By.CSS_SELECTOR,"body > div.container > div.right > div:nth-child(1) > div.date")self.driver.find_element(By.CSS_SELECTOR,"body > div.container > div.right > div:nth-child(1) > div.title")BlogDriver.screePhoto()
list=Bloglist()

根据测试用例,查找登录状态下的主页里昵称,地址,等元素,查找列表里博客标题,时间,简要内容等元素,以及检查相关功能等,测试结果截图保存


BlogDetailTest.py

from common.Utils import BlogDriver
from selenium.webdriver.common.by import Byclass Detail:url=""driver=""def __init__(self):self.url="http://8.137.19.140:9090/blog_detail.html?blogId=166703"self.driver=BlogDriver.driverself.driver.get(self.url)def DetailTest(self):self.driver.find_element(By.CSS_SELECTOR,"body > div.container > div.right > div > div.title")BlogDriver.screePhoto()
detail=Detail()

根据测试用例,检查登录状态下的相关的列表详情页元素,测试结果截图保存


BlogEidtTest.py

from common.Utils import BlogDriver
from selenium.webdriver.common.by import Byclass Eidt:url=""deriver=""def __init__(self):self.url = "http://8.137.19.140:9090/blog_edit.html"self.driver = BlogDriver.driverself.driver.get(self.url)def EditTest(self):BlogDriver.screePhoto()self.driver.find_element(By.CSS_SELECTOR,"#title").send_keys("4444")self.driver.find_element(By.CSS_SELECTOR, "#submit").click()BlogDriver.screePhoto()
eidt=Eidt()

根据测试用例,检查登录状态下的编辑页里的元素,检查是否能编写博客并发布,测试结果截图保存


最后在回归测试下所有接口

from tests import BlogLoginTest
from tests import BlogListTest
from tests import BlogDetailTest
from tests import BlogEidtTest
from common.Utils import BlogDriverif __name__ == "__main__":BlogLoginTest.BlogLogin().LoginFauTest()BlogLoginTest.BlogLogin().LoginSucTest()# #登陆成功之后就可以调用博客首页测试首页的用例(登陆状态)BlogListTest.Bloglist().testBlogList()# #测试登录状态下的博客详情页# BlogDetailTest.Detail().DetailTest()#博客编辑页面BlogEidtTest.Eidt().EditTest()#指定浏览器的退出BlogDriver.driver.quit()

自动化测试结果:通过


性能测试

性能测试工具

jmeter测试工具

用到的两个jmeter插件:Page Data Extractor和Custom Thread Groups

性能测试流程

创建一个测试系统性能的线程组

以20个线程为例做一个简单的性能测试,每5个线程在1s内执行,每间隔3s执行一次


创建http默认请求值

这个包含了所有请求哪一项不填,用到的是默认值在该页中,我们的id和端口号可以放在这里


分别创建登录,列表页,用户信息,详情页,添加博客对应请求,并通过结果树验证是否通过

注意

登录凭证在没有Cookie的情况下,需要添加到用到登录凭证的请求头中,否则连接失败,所以登录响应中的data需要提取出来到一个临时变量再添加到HTTP头管理器

详情页里访问的博客id可以指定成你在列表页中提取出来的id

在添加博客请求时,若访问失败,是content-type内容不同,需要在请求头里添加


查看响应时间图与吞吐量图

我们可以得知响应时间越高吞吐量越低是符合在性能测试下的预期,但我们发现最后线程退出时相应时间不短升高

我们再根据线程图观察到最后一个线程并没有退出来,我们再看下聚合报告,哪个页面响应时间长

分析原因

有聚合报告得知列表页响应时间过长,说明列表页存在问题,或许列表页响应数据太多,我们可以添加分页,来限制每页最大博客数,就可以减少响应时间


性能测试报告

生成测试报告命令:

结合生成的测试报告我们可以得知一共902个请求,全部通过,没有错误,说明该系统在高并发环境下可以运行

测试报告给出的响应时间也符合我们的猜测,列表页响应时间长


测试总结

本次测试,按照功能测试,自动化测试,性能测试方面对博客系统进行了测试,全部通过


结束语

博客系统测试报告结束

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

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Oracle:配置让插入语句时id自动输入

Oracle:配置让插入语句时id自动输入无需手动指定,核心是利用 序列(Sequence) 或 自增列(Identity Column) 来自动生成唯一值。以下是两种常用方案:方案 1:使用序列(Sequence&#xf…

秒杀服务的回调方案

在秒杀场景中,用户点击“抢购”后,后端需要通过异步处理应对高并发(避免请求阻塞),同时需通过实时回调机制将最终结果(成功/失败)推送给客户端并展示。核心方案是:“前端发起请求→后…

php apache无法接收到Authorization header

Apache 默认不传递 Authorization头到后端环境(如 PHP)。其表现是:print_r($_SERVER)时, 没有 [Authorization] :Array ([Accept-Language] > zh,en;q0.9,zh-CN;q0.8,en-US;q0.7[Accept-Encoding] > gzip, defla…

当我们想用GPU(nlp模型篇)

在个人设备上“把 GPU 真正用起来”做 NLP,分五步:准备 → 安装 → 验证 → 训练/推理 → 踩坑排查。下面每一步都给出可复制命令和常见错误。 ────────────────── 1. 硬件准备 • 一张 NVIDIA GPU,算力 ≥ 6.1&#xff08…

CryptSIPVerifyIndirectData函数分析

可以使用此函数从SIP接口对应的文件中提取签名信息 CryptSIPVerifyIndirectData:将当前文件的哈希结果做为“指纹”,并与从CryptSIPGetSignedDataMsg中提取的签名信息进行比较。 如果哈希结果相同,则意味着当前文件与之前签名的文件相同&…

20250823解决荣品RD-RK3588-MID开发板在充电的时候大概每10s屏幕会像水波纹闪烁一下

20250823解决荣品RD-RK3588-MID开发板在充电的时候大概每10s屏幕会像水波纹闪烁一下 2025/8/23 17:58【结论】:使用直流电源供电,给电池【快速】充电,但是直流电源的电压稳定,电流抖动导致的!那个是2.4G 已经知道了我司…

CANN安装

前提条件 请参考本文档正确安装和使用CANN软件,不建议将CANN安装在共享磁盘后,通过挂载的方式使用CANN,因为CANN对文件系统有文件锁的依赖,部分共享存储不支持文件锁,可能导致任务拉起失败。 root用户和非root用户安装CANN软件包的步骤一致,当前示例步骤以非root用户为例…

docker的基础配置

目录 数据卷 数据卷容器 端口映射与容器互联 互联机制实现便捷互访(基于容器搭建论坛) 数据卷 1.创建数据卷 [rootopenEuler-1 /]# docker volume create test test [rootopenEuler-1 /]# docker volume ls DRIVER VOLUME NAME local test [ro…

VSCode Import Cost:5 分钟学会依赖瘦身

一句话作用:在代码里 import 时,实时显示包大小,帮你一眼揪出体积炸弹。1️⃣ 30 秒安装 & 启动 打开 VSCode → 扩展商店搜索 Import Cost → 安装重启 VSCode,立即生效,零配置。2️⃣ 使用方式(开箱即…

TCP/UDP详解(一)

UDP报文源端口16bit 目的端口16bit校验和checksum16bit 总长度16bit--------------------------------------------------------------------------------------------------------------------------源目端口用于标识应用层协议,分为知名端口&#x…

数据库优化提速(一)之进销存库存管理—仙盟创梦IDE

从存储过程到通用 SQL:进销存系统的数据操作优化在进销存系统的开发与维护中,数据库查询语句的编写方式对系统的性能、兼容性和可维护性有着深远影响。本文将围绕给定的三段 SQL 代码展开,深入探讨将存储过程转换为通用 SQL 在进销存场景下的…

Redis面试精讲 Day 28:Redis云原生部署与Kubernetes集成

【Redis面试精讲 Day 28】Redis云原生部署与Kubernetes集成 在当今微服务与容器化浪潮中,Redis作为高性能缓存和消息中间件,已从单机部署逐步演进为云原生环境下的核心组件。Day 28 聚焦“Redis云原生部署与Kubernetes集成”,深入解析如何在…

leetcode刷题记录03——top100题里的6道简单+1道中等题

leetcode刷题记录03——top100题里的6道简单1道中等题上一篇博客: leetcode刷题记录01——top100题里的7道简单题 leetcode刷题记录02——top100题里的7道简单题 有效的括号 看懂需要用栈了,但是不知道怎么去写,看了题解mark下正确答案。 cla…

求单位球内满足边界条件 u = z³ 的调和函数

问题 6:在区域 {x2y2z2≤1}\{x^{2}y^{2}z^{2}\leq 1\}{x2y2z2≤1} 内找到一个调和函数 uuu,使得在边界 x2y2z21x^{2}y^{2}z^{2}1x2y2z21 上,uuu 等于 gz3gz^{3}gz3。 提示:根据第8.1节,解必须是一个三次调和多项式&…

AAA 服务器与 RADIUS 协议笔记

一、AAA 服务器概述1. 核心定义AAA 是认证(Authentication)、授权(Authorization)和计费(Accounting) 的简称,是网络安全领域中实现访问控制的核心安全管理机制,通过整合三种服务确保…

Vue3源码reactivity响应式篇之数组代理的方法

概览 vue3中对于普通的代理包含对象和数组两类,对于数组的方法是重写了许多方法,具体实现参见packages\reactivity\src\arrayInstrumentations.ts arrayInstrumentations实际上就是一个对象,对象的属性就是数组的方法,属性值就是重…

如何玩转K8s:从入门到实战

一、K8S介绍及部署 1 应用的部署方式演变 部署应用程序的方式上,主要经历了三个阶段: 传统部署:互联网早期,会直接将应用程序部署在物理机上 优点:简单,不需要其它技术的参与 缺点:不能为应用…

综合测验:配置主dns,dhcp,虚拟主机,nfs文件共享等

综合实验(所有设备关闭防火墙和selinux)在appsrv上部署主dns,为example.com提供域名解析 安装bind bind-chroot rootappsrv ~]# yum install bind bind-chroot -y编辑主配置文件,全局配置文件,正向解析文件 [rootappsrv ~]# vim /etc/named.c…

MySQL数据库管理与索引优化全攻略

一、表管理1.建库语法:create database if not exists 数据库名;命名规则:仅可使用数字、字母、下划线、不能纯数字;区分字母大小写;具有唯一性;不可使用MySQL命令或特殊字符。相关命令:show databases; …

基于大模型构建 Java 混淆的方式方法(从入门到精通 · 含开源实践)

1. 目标与威胁模型:你到底想防什么? 把“混淆”当作成本叠加器:让逆向者付出更多时间与技能,而不影响用户体验与可维护性。可用 Collberg 等提出的四指标来权衡:有效性/韧性/隐蔽性/成本(potency/resilience/stealth/cost)。近年的研究也在重审这些评估方法,建议结合可…