【功能测试+UI自动化测试+性能测试】BitNote博客系统测试文档
BitNote博客系统测试文档
一、项目背景
- 在软件技术的学习与实践过程中,开发者每天都会接触大量的新知识、解决各种技术难题并积累宝贵的实战经验。
- 然而,这些有价值的内容往往被零散地记录在不同的地方,如本地文档、云笔记或代码注释中,导致知识管理碎片化、内容检索困难、经验分享效率低下等问题。
- 为解决上述痛点,我们开发了
BitNote博客系统。 - 本项目旨在为技术人员提供一个专属的、系统化的在线知识管理平台,将分散的学习笔记与技术心得进行有效整合,并通过博客的形式进行沉淀与分享。
- 为了确保该系统在上线后能够稳定、可靠地运行,为用户提供流畅的使用体验,现计划对
BitNote系统进行全面、严格的质量保障测试。 - 本测试文档旨在验证登录博客、发布博客、重新编辑博客、删除博客、查看博客、退出博客等业务逻辑是否正确。
二、项目简介
BitNote 是一个轻量级个人博客系统,核心目标是为用户提供一个纯粹、高效的在线笔记与博客管理体验。
系统围绕博客文章的核心生命周期,设计了四个主要功能页面:
-
用户登录页:系统唯一入口,通过账号密码进行身份验证。
-
博客首页:双栏布局,左侧展示个人信息,右侧展示全部博客列表。
-
博客详情页:展示博客完整内容,作者可在此进行编辑或删除操作。
-
博客编辑页:集成
Markdown编辑器的页面,用于创建新博客或更新已有博客。
核心功能涵盖了完整的博客管理操作,包括:用户登录、发布新博客、重新编辑已有博客、删除博客、查看博客详情以及安全退出。
三、测试用例
通常,软件测试涵盖功能、性能、界面、易用性、安全及兼容性六大方面。
结合BitNote博客系统主要由前端页面和后端接口构成的特点,本次测试策略将聚焦于功能测试、自动化测试与性能测试三个核心维度,以确保系统核心业务的正确性、稳定性和执行效率。
具体测试范围包括:
-
功能测试:针对用户登录页、博客首页、博客详情页及博客编辑页四个主要功能界面进行验证。
-
自动化测试:对上述四个页面的核心交互流程编写自动化脚本,用于回归测试。
-
性能测试:对系统5个关键接口进行压力测试,重点分析其错误率、活跃线程数、响应时间及吞吐量等性能指标。
基于以上测试范围与策略,我们设计了如下结构的测试用例:

四、测试工具
一、测试用例编写工具
Xmind思维导图 - 测试用例设计和思维导图绘制
二、自动化测试工具
PyCharm- Python集成开发环境Python 3.11- 编程语言环境selenium 4.0.0- Web自动化测试框架webdriver-manager- 浏览器驱动管理工具
三、性能测试工具
Postman- API接口测试工具JMeter- 性能负载测试工具JDK17- Java开发环境jmeter-plugins-manager-1.11.jar- JMeter插件管理工具Page Data Extractor插件 - 页面数据提取插件Custom Thread Groups插件 - 自定义线程组插件jpgc - Standard Set插件 - 标准插件集Basic Graphs插件 - 基础图表插件
五、手动测试
用户登录页
1、登录界面展示
测试步骤: 访问系统登录页面
预期效果: 正常显示登录界面,包含用户名输入框、密码输入框和提交按钮
实际效果:登录界面正常显示,所有表单元素完整可见

2、正常登录测试
测试步骤: 在用户名输入框输入"zhangsan",密码输入框输入"123456",点击提交按钮
预期效果: 登录成功,自动跳转到博客列表页
实际效果:系统成功验证用户信息,正常跳转到博客首页,显示博客列表


3、错误用户名测试
测试步骤: 在用户名输入框输入"zhangsan_“,密码输入框输入"123456”,点击提交按钮
预期效果: 弹出提示弹窗,显示"用户不存在"
实际效果:系统检测到用户名不存在,正确弹出提示窗口显示"用户不存在"

4、错误密码测试
测试步骤: 在用户名输入框输入"zhangsan",密码输入框输入"12345",点击提交按钮
预期效果: 显示"密码错误"提示信息
实际效果: 系统验证密码错误,正确显示"密码错误"提示信息

5、错误用户名和密码测试
测试步骤: 在用户名输入框输入"zhangsa",密码输入框输入"1234567",点击提交按钮
预期效果: 显示"用户不存在"提示信息
实际效果:系统检测到用户名不存在,正确显示"用户不存在"提示信息

博客首页
1、个人信息展示和列表区展示
测试步骤: 成功登录后查看博客首页
预期效果:
- 左侧个人信息区显示:头像、昵称、发布文章数量、分类数量
- 右侧列表区显示每篇博客的:标题、发布时间、博客内容摘要、"查看全文"按钮
实际效果: 个人信息和博客列表均正常显示,所有元素完整可见

2、退出博客功能
测试步骤: 点击"注销"按钮
预期效果: 成功退出登录,跳转回登录页面,账号密码输入框为空
实际效果: 系统成功退出登录,返回登录页面,输入框内容已清空


博客详情页
1、本账号发布的博客详情页展示
测试步骤: 点击查看本账号发布的博客详情
预期效果: 显示博客标题、发布时间、完整博客内容,以及"编辑"和"删除"按钮
实际效果: 博客详情内容完整显示,"编辑"和"删除"按钮正常可见

2、非本账号发布的博客详情页展示
测试步骤: 点击查看其他账号发布的博客详情
预期效果: 显示博客标题、发布时间、完整博客内容,不显示"编辑"和"删除"按钮
实际效果: 博客详情内容完整显示,无"编辑"和"删除"按钮

3、删除博客功能
测试步骤: 在本账号博客详情页点击"删除"按钮,在确认弹窗中确认删除
预期效果: 博客删除成功,跳转回首页,博客列表中不再显示被删除的博客
实际效果: 博客成功删除,返回首页后列表刷新,被删除博客不再显示


博客编辑页
1、编辑页面展示
测试步骤: 在首页点击"写博客"按钮进入编辑页面
预期效果: Markdown编辑器正常加载,可以正常输入标题和文章内容
实际效果: 编辑页面正常显示,标题输入框和Markdown编辑器功能正常

2、发布新博客功能
测试步骤: 通过"写博客"按钮进入编辑页,输入标题和文章内容,点击"发布文章"按钮
预期效果: 博客发布成功,跳转到首页,博客列表中显示新发布的博客,发布时间正确
实际效果: 博客成功发布,首页列表更新,新发布的博客正常显示


3、更新已有博客功能
测试步骤: 通过博客详情页的"编辑"按钮进入编辑页,修改标题和内容,点击"更新文章"按钮
预期效果: 博客更新成功,跳转到首页,博客列表中的博客内容更新,发布时间保持不变
实际效果: 博客成功更新,首页列表中的博客内容已修改,发布时间未改变



六、自动化测试
在当前敏捷开发与快速迭代的背景下,为确保BitNote博客系统在频繁的功能更新与代码变更中始终保持核心业务流程的稳定性与正确性,引入自动化测试已成为保障软件质量、提升交付效率的关键环节。通过将重复性高、逻辑固定的测试场景(如用户登录、博客增删改查等)转化为自动化脚本,不仅能够实现快速、准确的回归验证,有效规避人为测试的疏漏与不一致性,更能为持续集成/持续交付流程提供可靠的质量保障,支撑系统高效、稳定地迭代与发展。
环境安装
1.环境准备
PyCharm:Python集成开发环境Python 3.11:编程语言环境Selenium 4.0.0:Web自动化测试框架webdriver-manager:浏览器驱动管理工具


2.安装步骤
- 在PyCharm中新建项目并选择本地Python环境
- 在Settings中的
Python Interpreter添加Selenium 4.0.0和webdriver-manager软件包


或者

编写自动化测试脚本
1.项目目录
BlogAutoTest/ # 自动化测试项目根目录
├── common/ # 公共组件目录
│ └── Utils.py # 工具类:浏览器驱动、截图功能等
├── images/ # 测试截图存储目录
│ └── 2025-09-21/ # 按日期分类的截图文件夹
└── tests/ # 测试脚本目录
├── BlogDetail.py # 博客详情页测试脚本
├── BlogEdit.py # 博客编辑页测试脚本
├── BlogList.py # 博客首页测试脚本
├── BlogLogin.py # 用户登录页测试脚本
└── RunTests.py # 聚合测试执行脚本
2.自动化测试代码
2.1添加配置文件
创建Python包common,并在里面添加Python文件Utils.py:
功能说明:
-
创建一个驱动对象,包含三个构造函数:
-
对象成员的构造函数
-
两个截图函数(系统级别截图用于截取弹窗,页面级别截图用于执行结果记录)
-
退出浏览器函数
代码实现:
import datetime
import os.path
import sys
import time
from fileinput import filename
from msilib.text import dirname
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.edge.service import Service
from selenium.webdriver.edge.options import Options
from selenium.webdriver.ie.webdriver import WebDriver
from selenium.webdriver.support import expected_conditions
from selenium.webdriver.support.wait import WebDriverWait
import webdriver_manager.microsoft
from webdriver_manager.microsoft import EdgeChromiumDriverManager
class Driver:
driver=""
def __init__(self):
edge_driver_path = r"D:\桌面\驱动器\msedgedriver.exe"
service = Service(edge_driver_path)
options = Options()
options.add_argument("--remote-allow-origins=*")
self.driver = webdriver.Edge(service=service, options=options)
self.driver.implicitly_wait(2)
def GetScreenshot(self):
# ../images/year-month-day/调用方法-year-month-day-hms.png
dirname=datetime.datetime.now().strftime("%Y-%m-%d")
# 判断dirname文件夹是否已经存在,若不存在则创建文件夹
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()
2.2 用户登录页自动化测试
测试内容:
- 在密码输入框中分别输入账号和密码,错误的测试用例是否登录失败并弹出提示;
- 正确的测试用例是否登录成功并在首页中找到个人信息区的元素
测试流程:
-
创建Python包tests,并在里面添加Python文件BlogLogin.py
-
创建一个
BlogLogin的类,定义成员变量driver和url,以及构造函数和四个测试用例函数 -
创建对象,设计执行步骤并运行全部函数,执行过程中进行截图
注意:在输入框中输入内容时要先执行清空操作,避免造成字符串拼接导致出错
# tests/BlogLoginTest.py
import time
from selenium.webdriver.common.by import By
from common.Utils import Blogdriver
class BlogLoginTest:
def __init__(self):
self.driver = Blogdriver.driver
self.url = "http://8.137.19.140:9090/blog_login.html"
self.driver.get(self.url)
def LoginSucTest(self):
try:
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()
time.sleep(1)
s = self.driver.find_element(By.CSS_SELECTOR, "body > div.container > div.left > div > h3").text
time.sleep(1)
print(s)
assert s == "zhangsan"
# 正确调用截图方法
Blogdriver.GetScreenshot()
self.driver.back()
except Exception as e:
print(f"登录成功测试失败: {e}")
Blogdriver.GetScreenshot()
raise
def LoginFailTest(self):
try:
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()
Blogdriver.GetScreenshot()
time.sleep(1)
alert = self.driver.switch_to.alert
alert.accept()
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("12345")
self.driver.find_element(By.CSS_SELECTOR, "#submit").click()
Blogdriver.GetScreenshot()
time.sleep(1)
alert = self.driver.switch_to.alert
alert.accept()
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("1234567")
self.driver.find_element(By.CSS_SELECTOR, "#submit").click()
Blogdriver.GetScreenshot()
time.sleep(1)
alert = self.driver.switch_to.alert
alert.accept()
except Exception as e:
print(f"登录失败测试失败: {e}")
Blogdriver.GetScreenshot()
raise

2.3 博客首页自动化测试
测试内容:
- 未登录状态下通过网址进入首页,会退回到登录页;
- 登录状态下进入首页,查找个人信息相关元素(当前登录的用户头像、昵称、发布文章及数量和分类及数量),以及博客列表区其中一篇博客的基本元素(包括标题、时间、博客内容、"查看全文"按钮)
测试流程:
-
在Python包tests中添加Python文件BlogList.py
-
创建一个BlogList的类,并定义两个成员变量driver和url,以及一个构造函数和两个测试用例函数
-
创建对象,设计执行步骤并运行全部函数,执行过程中进行截图
# 博客首页测试用例
import unittest
from selenium.webdriver.common.by import By
from common.Utils import Blogdriver
class BlogListTest:
url=""
driver=""
def __init__(self):
self.url="http://8.137.19.140:9090/blog_list.html"
self.driver=Blogdriver.driver
self.driver.get(self.url)
# 测试首页(登陆情况下)
def ListTestByLogin(self):
# 查找博客列表元素:标题、发布时间、内容、"查看详情"按钮
t=self.driver.find_element(By.CSS_SELECTOR, "body > div.container > div.right > div:nth-child(1) > div.title").text
self.driver.find_element(By.CSS_SELECTOR, "body > div.container > div.right > div:nth-child(1) > div.desc")
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) > a")
# 查找博客个人信息:头像、昵称、文章、文章数量、分类、分类数量
self.driver.find_element(By.CSS_SELECTOR, "body > div.container > div.left > div > img")
s=self.driver.find_element(By.CSS_SELECTOR, "body > div.container > div.left > div > h3").text
self.driver.find_element(By.CSS_SELECTOR,
"body > div.container > div.left > div > div:nth-child(4) > span:nth-child(1)")
self.driver.find_element(By.CSS_SELECTOR,
"body > div.container > div.left > div > div:nth-child(4) > span:nth-child(2)")
self.driver.find_element(By.CSS_SELECTOR,
"body > div.container > div.left > div > div:nth-child(5) > span:nth-child(1)")
self.driver.find_element(By.CSS_SELECTOR,
"body > div.container > div.left > div > div:nth-child(5) > span:nth-child(2)")
print(s)
print("第一篇文章标题: "+t);
# 屏幕截图记录
Blogdriver.GetScreenshot()


2.4 博客详情页自动化测试
测试内容:
- 未登录状态下通过网址进入博客详情页,会退回到登录页;
- 登录状态下进入详情页,页面会显示该博客的基本元素(标题,发布时间以及博客详情内容),查找元素是否存在,从而检查页面是否正常;
- 若是本账号发布,还可以看到"编辑"按钮和"删除"按钮
测试流程:
- 在Python包tests中添加Python文件BlogDetail.py
- 创建一个
BlogDetail的类,并定义两个成员变量driver和url,以及一个构造函数和两个测试用例函数 - 创建对象,设计执行步骤并运行全部函数,执行过程中进行截图
import time
from selenium.webdriver.common.by import By
from common.Utils import Blogdriver
class BlogDetailTest:
url=""
driver=""
def __init__(self):
self.url="http://8.137.19.140:9090/blog_detail.html?blogId=158477"
self.driver=Blogdriver.driver
self.driver.get(self.url)
# 博客详情页测试(登录状态下)
def DetailTestByLogin(self):
# 查找博客文章详情元素:标题、发表时间、内容
time.sleep(1)
self.driver.find_element(By.CSS_SELECTOR, "body > div.container > div.right > div > div.title")
self.driver.find_element(By.CSS_SELECTOR, "body > div.container > div.right > div > div.date")
self.driver.find_element(By.CSS_SELECTOR, "#detail > p")
# 查找博客个人信息:头像、昵称、文章、文章数量、分类、分类数量
self.driver.find_element(By.CSS_SELECTOR, "body > div.container > div.left > div > img")
self.driver.find_element(By.CSS_SELECTOR, "body > div.container > div.left > div > h3")
self.driver.find_element(By.CSS_SELECTOR,
"body > div.container > div.left > div > div:nth-child(4) > span:nth-child(1)")
self.driver.find_element(By.CSS_SELECTOR,
"body > div.container > div.left > div > div:nth-child(4) > span:nth-child(2)")
self.driver.find_element(By.CSS_SELECTOR,
"body > div.container > div.left > div > div:nth-child(5) > span:nth-child(1)")
self.driver.find_element(By.CSS_SELECTOR,
"body > div.container > div.left > div > div:nth-child(5) > span:nth-child(2)")
# 屏幕截图记录
Blogdriver.GetScreenshot()
print("title:>" + self.driver.find_element(By.CSS_SELECTOR,
"body > div.container > div.right > div > div.title").text)
print("writer:>" + self.driver.find_element(By.CSS_SELECTOR,
"body > div.container > div.left > div > h3").text)
# 未登录状态下的博客详情的测试用例
def DetailByNotLogin(self):
# 会自动跳转回登录页
time.sleep(0.5)
current_url = self.driver.current_url
assert current_url != self.url
print("DetailByNotLogin-before_url:" + self.url)
print("DetailByNotLogin-after_url:" + current_url)
# 屏幕截图记录
Blogdriver.GetScreenshot()



2.5 博客编辑页自动化测试
测试内容:
- 未登录状态下通过网址进入博客编辑页,会退回到登录页;
- 登录状态下进入编辑页,等待页面加载完成后,输入标题内容并发布,发布完成后会回到首页并刷新,列表会显示出刚刚发布的博客
测试流程:
-
在Python包tests中添加Python文件BlogEdit.py
-
创建一个BlogEdit的类,并定义三个成员变量driver、url和wait,以及一个构造函数和两个测试用例函数
-
创建对象,设计执行步骤并运行全部函数,执行过程中进行截图
import time
from time import sleep
from selenium.webdriver import Keys
from selenium.webdriver.common.by import By
from common.Utils import Blogdriver
class BlogEditTest:
url=""
driver=""
def __init__(self):
self.url="http://8.137.19.140:9090/blog_edit.html"
self.driver=Blogdriver.driver
self.driver.get(self.url)
def EditTestbyLogin(self):
s="This is a Autotest"
sleep(1)
self.driver.find_element(By.CSS_SELECTOR,"#title").send_keys(s)
sleep(1)
# 编辑区域是个插件,不可操作
self.driver.find_element(By.CSS_SELECTOR,"#submit").click()
time.sleep(1)
# 跳转页面需要时间,所以加载的速度可能比渲染的速度要快,导致元素查找不到,因此可以添加等待
# 显示/隐式等待 任其一
# 隐式等待:创建浏览器对象后就可以加上,因为隐式等待的作用域在driver整个生命周期
# 显示等待:可以作用到当前代码中
Blogdriver.GetScreenshot()
text = self.driver.find_element(By.CSS_SELECTOR,
"body > div.container > div.right > div:nth-child(2) > div.title").text
Blogdriver.GetScreenshot()
assert s == text
print("title: " + text)
# 未登录状态下的博客编辑的测试用例
def EditByNotLogin(self):
sleep(1)
s = "This is a Autotest"
# 输入博客文章标题和内容并发布
self.driver.find_element(By.CSS_SELECTOR, "#title").send_keys(s)
# 屏幕截图记录
Blogdriver.GetScreenshot()
self.driver.find_element(By.CSS_SELECTOR, "#submit").click()
# 会自动跳转回登录页
time.sleep(0.5)
current_url = self.driver.current_url
assert current_url != self.url
print("EditByNotLogin-before_url:" + self.url)
print("EditByNotLogin-after_url:" + current_url)
# 屏幕截图记录
Blogdriver.GetScreenshot()


2.6 回归测试
测试内容:
- 将四个页面功能按照一定顺序排列出来,并进行一次完整的测试,从而检查页面是否存在问题
测试流程:
-
在Python包tests中添加Python文件RunTests.py
-
创建__main__
-
创建对象,设计执行步骤并运行全部函数,执行过程中进行截图
from tests import BlogListTest
from tests import BlogDetailTest
from tests import BlogLoginTest
from tests import BlogEditTest
from common.Utils import Blogdriver
if __name__ == '__main__':
BlogLoginTest.BlogLoginTest().LoginFailTest()
BlogLoginTest.BlogLoginTest().LoginSucTest()
# 要保证在登陆成功状态下,因为这样才能进入首页
BlogListTest.BlogListTest().ListTestByLogin()
BlogDetailTest.BlogDetailTest().DetailTestByLogin()
BlogDetailTest.BlogDetailTest().DetailByNotLogin()
BlogEditTest.BlogEditTest().EditTestbyLogin()
# 没有登陆的情况下
BlogEditTest.BlogEditTest().EditByNotLogin()
Blogdriver.driver.quit()

七、性能测试
1.相关工具使用说明
1.1 测试工具介绍
Apache JMeter:基于Java开发的开源性能测试工具,用于对系统进行压力测试和性能分析
JMeter
1.1.1 安装JMeter
环境要求:

Apache JMeter 是 Apache 组织基于 Java 开发的压⼒测试⼯具,⽤于对软件做性能测试。
1.下载tar包,解压即可。
apache-jmeter-5.5.tgz

解压完成后:

1.1.2 打开JMeter
⽅式⼀:点击bat⽂件

⽅式⼆:命令⾏启动(推荐)
step1:添加JMeter系统环境变量

step2:保存后打开命令⾏⼯具

输⼊命令jmeter即可启动JMeter⼯具
1.1.3 JMeter基础配置
• 修改字体为中⽂

在jmeter的bin⽬录下,修改⽂件中的内容:language=zh_CN
Postman
Postman:用于接口测试和验证,在JMeter配置前进行接口功能验证

1.2 接口获取方法
通过浏览器开发者工具获取接口信息:
-
按F12打开开发者工具
-
选择Network选项卡
-
选择Fetch/XHR过滤器
-
在Name列表中选择具体请求
-
在右侧查看接口地址和请求方法

2.性能测试相关配置
2.1 通用配置文件
JMeter重要组件
1 线程组
控制JMeter将⽤于执⾏测试的线程数,也可以把⼀个线程理解为⼀个测试用户。

线程数:⼀个线程即⼀个测试用户,设置发送的请求次数
Ramp-up时间(秒):设置性能测试运行时间,单位为秒
循环次数:
- 配置指定次数:控制脚本循环执⾏的次数
- 配置循环永远
- 需要调度器配置使⽤
- 运⾏时间:脚本执行时间
- 延迟启动时间:脚本等待指定时间才能运⾏
2 HTTP取样器


添加必需的配置:
-
http协议
-
http主机名/IP
-
端⼝
-
http协议端⼝号80
-
https端⼝号443
-
-
请求⽅法
-
路径(⽬录+参数)
-
内容编码(默认的ISO国际标准,但对中文支持不友好,可以使⽤utf-8)
-
参数
-
参数可以拼在路径⾥,也可以卸载参数中
-
POST参数要放到消息体数据中{wd:test}
-
3 查看结果树
取样器结果:统计请求相关的信息


1 Thread Name:线程组名称
2 Sample time:发送请求时间
3 load time:响应时间
4 Response code :接口响应状态码
请求:HTTP请求的请求头和请求体的详细信息
响应:HTTP响应的响应头和响应体的详细信息
4 HTTP Cookie管理器
HTTP Cookie管理器像Web浏览器⼀样存储和发送Cookie。如果HTTP请求并且响应包含cookie,则Cookie管理器会⾃动存储该cookie,并将其⽤于将来对该特定⽹站的所有请求。
每个JMeter线程都有⾃⼰的"cookie存储区"。因此,正在测试使⽤cookie存储会话信息的⽹站,则每个JMeter线程都将拥有⾃⼰的会话。此类Cookie不会显⽰在Cookie管理器显⽰屏上,可以使⽤"查看结果树监听器"查看。
缓存配置可选择standard(标准)或compatibility(兼容的),当然也可以⼿⼯添加⼀些cookie.
添加了HTTP Cookie管理器后,会⾃动存储并发送Cookie


5 HTTP请求默认值
博客中涉及到的接⼝协议、IP、端⼝号全都⼀样,可以单独抽取出来存放在默认值中,其他接⼝就可以省略不写协议、IP、端⼝号


6 用户定义的变量
添加⽅式:线程组—配置元件—⽤⼾定义的变量
- 有时我们只想要在固定的场景⾥使⽤参数化,改动后不希望影响到其他的脚本。
使⽤:在HTTP请求的取样器中引⼊定义的变量。${参数名}

适⽤场景:变量需要在多个脚本中使⽤,⽅⾯统⼀管理和修改

7 CSV数据⽂件设置
以登陆接⼝为例,当我们执⾏登陆接⼝的性能测试时,⼿动配置了⽤⼾名和密码为固定的username和password,然⽽实际使⽤中不可能只有⼀个⽤⼾登陆,为了模拟更真实的登录环境,我们需要提供更多的⽤⼾username和password来实现登录操作
添加⽅式:线程组⸺配置元件⸺CSV数据⽂件设置

2.7.1 操作步骤
1)CSV数据⽂件设置
- ⽂件名:填写csv⽂件的路径。建议使⽤绝对路径。
- ⽂件编码:UTF-8
- 变量名称:从csv数据⽂件中读起的数据需要保存到的变量名。有多个变量时⽤逗号分隔
- 是否忽略⾸⾏:是否从csv数据⽂件第⼀⾏开始读取。
- 分隔符:要求与csv数据⽂件中多列的分隔符⼀致
- 遇到⽂件结束符再次循环:若选择为True当数据不够的时候会从头取。若选择False,则需要勾选下⾯的配置,遇到⽂件结束符停⽌线程,这⾥如果不勾选,请求将会报错。

2)编写test.csv⽂件,⽰例:

3)修改登陆接⼝及其他涉及到username和password获取的参数

修改完该配置后,登陆接⼝发起请求时将从csv⽂件中获取配置好的username和password参数,获取顺序为从上往下依次获取
4)修改线程组中线程数,使得每次取到的username和password都不⼀样

5)运⾏结果


8 JSON提取器
接⼝响应成功,通过提取返回值对应字段,可⽤于其他接⼝的参数配置
1)添加JSON提取器
针对某⼀个HTTP请求接⼝添加JSON提取器
案例:以博客⾸⻚为例


JSON操作符参考:
| Operator | Description |
|---|---|
| $ | 表示根元素 |
| @ | 当前元素 |
| * | 通配符。所有节点 |
| … | 选择所有符合条件的节点 |
| . | 子元素 |
| [‘’, ‘’] | 括号表示子元素或子元素列表 |
| [, ] | 数组索引或索引列表 |
| [start:end] | 数组切片操作符 |
| [?] | 过滤器表达式。表达式必须评估为布尔值 |
参考⽂档:https://github.com/json-path/JsonPath
获取相应中的所有blogId元素:$..blogId
获取第⼀个blogId元素:$.[0]blogId
2)添加JSON配置
3)配置json提取的参数
运⾏脚本后,所有的查看博客内容接⼝对应的blogId统⼀替换为12
9 JSON断⾔
接⼝发送请求成功,响应码为200并不能完全代表接⼝请求成功,我们更多需要关注接⼝响应数据是否符合预期。


1)添加JSON断⾔:
针对某⼀个HTTP请求接⼝添加JSON断⾔
2)添加JSON配置
同JSON提取器语法配置
注意:
- 1)若不选Additionally assert value,表⽰添加断⾔值,则可⽤来判断字段是否存在
- 2)选择Additionally assert value,则必须添加Expected Value期望的断⾔值
- 3)若不选Match as regular expression正则匹配,则Expected Value必须填写完整,少⼀个字符都会导致断⾔失败
- 4)若选择Match as regular expression正则匹配,则Expected Value可以仅写上部分关键词即可断⾔成功
10 同步定时器(集合点)
为了达到并发的效果,需要添加同步定时器JMeter同步定时器的作⽤主要在于模拟多⽤⼾并发访问的场景,确保多个线程能够同时执⾏某个操作,以达到真正的并发效果。
当多个线程同时启动时,它们可能会在不同的时间间隔内执⾏,这样就⽆法达到真正的并发效果。同步定时器的作⽤就是将这些线程的执⾏时间同步,使它们在同⼀时间点执⾏。它可以在多个线程之间制造⼀定的延迟,直到同时到达指定时间点,再同时执⾏后续的操作。
此外,同步定时器可以理解为集合点,当线程数量达到指定值后,再⼀起释放,可以瞬间产⽣很⼤的压⼒。这样,可以更好地模拟真实的⽤⼾并发访问场景,提⾼测试的准确性和可靠性。
在性能测试过程中,为了真实模拟多个⽤⼾同时进⾏操作以度量服务器的处理能⼒,可以使⽤同步定时器来设置集合点。不过,虽然通过加⼊集合点可以约束请求同时发送,但不能确保请求同时到达服务器,所以只能说是较真实模拟并发。


现实⽣活中,红绿灯就相当于⼀个集合点,有⼈先到达,有⼈后达到,但必须等到绿灯后所有⼈才能开始过⼈⾏道。
11 事务控制器
JMeter事务控制器的作⽤主要⽤于测试执⾏嵌套测试元素所花费的总时间。这相当于模拟用户进⾏⼀系列操作的测试。

在进⾏⻚⾯性能测试或API性能测试时,事务控制器是⼀个⾮常重要的⼯具。它可以帮助测试⼈员更准确地评估系统性能,尤其是在涉及多个接⼝或操作的复杂场景中。
- 例如,在订单提交的过程中,可能需要调⽤多个接⼝,并且某些接⼝可能依赖于前⼀个接⼝的结果。在这种情况下,使⽤事务控制器可以将这些接⼝统⼀视为⼀个事务进⾏性能测试,从⽽得到更接近真实场景的性能测试结果。
- 若不添加事务控制器,则⼀个接⼝即⼀个事务。
- 添加了事务控制器后,可以将多个接⼝统⼀放到⼀个事务控制器下作为⼀个事务。
12 Jmeter插件
下载Jmeter插件功能:
https://jmeter-plugins.org/install/Install/
将下载好的插件放到jmeter下lib/ext⽂件夹下:

此时,jmeter界⾯右上⻆将会展⽰⼀个⼩蝴蝶形状的⼯具,该⼯具即jmeter插件功能,点击该功能可以下载jmeter中⽀持的各种插件:

在真实企业压测场景中,我们通常为⼀点⼀点的逐步增加线程数,因此需要安装新的插件来⽀持线程数的配置。
通过插件管理⼯具下载其他插件:
1)在插件中下载其他监听器插件

2)在插件中下载线程组插件

点击Apply Changes and Restart JMeter等待下载完成并重启JMeter:
下载完成后再线程和监听器中可以看到新增的元件:

2.12.1 Stepping Thread Group
梯度压测线程组

- This group will start:启动多少个线程,同线程组中的线程数
- First, wait for:等待多少秒才开始压测,⼀般默认为0
- Then start:⼀开始有多少个线程数,⼀般默认为0
-
Next,add:下⼀次增加多少个线程数
-
threads every:当前运⾏多⻓时间后再次启动线程,即每⼀次线程启动完成之后的的持续时间;
-
using ramp-up:启动线程的时间;若设置为5秒,表⽰每次启动线程都持续5秒
-
thenhold loadfor:线程全部启动完之后持续运⾏多⻓时间
-
finally,stop/threadsevery:多⻓时间释放多少个线程;若设置为5个和1秒,表⽰持续负载结束之后,每1秒钟释放5个线程
13 常见监听器
2.13.1 聚合报告
从聚合报告可以看到性能测试过程中整体的数据变化


2.13.2 Response Times Over Time
Response Times Over Time主要⽤于监听整个事务运⾏期间的响应时间。在测试过程中,它可以帮助测试⼈员观察并分析响应时间的实时平均值以及整体响应时间的⾛向。

通过这⼀监听器,测试⼈员能够更直观地了解系统在不同时间点的响应性能,从⽽发现可能存在的性能问题或瓶颈。
Response Times Over Time的图形展⽰中,横坐标通常代表运⾏时间,⽽纵坐标则代表响应时间(单位是毫秒)。测试⼈员可以根据图形中的趋势线来判断响应时间的稳定性以及是否存在⼤的波动。
- 例如,如果响应时间在某个时间点突然增加,这可能意味着系统在该时间点遇到了性能问题。
2.13.3 Transactions per Second(TPS)
JMeter中的Transactions per Second(TPS)监听器是⼀个⽤于分析系统吞吐量的重要⼯具。

TPS,即每秒事务数,表⽰⼀个客⼾机向服务器发送请求后服务器做出反应的过程。这个指标反映了系统在同⼀时间内处理业务的最⼤能⼒。TPS值越⾼,说明系统的处理能⼒越强。
在使⽤TPS监听器时,横坐标通常代表运⾏时间,⽽纵坐标则代表TPS值。通过监听器展⽰的图表,可以清晰地看到TPS值随时间的变化情况。在图表中,红⾊通常表⽰通过的TPS,⽽绿⾊可能表⽰失败的TPS。这有助于我们快速识别系统性能的变化和瓶颈。
JMeter基本使用流程
1)启动JMeter
2)在“测试计划”下添加“线程组”


3)在“线程组”下添加“HTTP”取样器

4)填写“HTTP请求”的相关请求数据

5)在“线程组”下添加“查看结果树”监听器

6)点击“启动”按钮运⾏,查看接⼝测试结果

3.测试报告
JMeter测试报告是⼀个全⾯⽽详细的⽂档,它提供了关于测试执⾏结果的详细信息,帮助⽤⼾全⾯评估系统的性能并进⾏性能优化。
⽣成性能测试报告的命令:
Jmeter -n -t 脚本文件 -l 日志文件 -e -o 目录
-n : 无图形化运行
-t : 被运行的脚本
-l : 将运行信息写入日志文件,后缀为jtl的日志文件
-e : 生成测试报告
-o : 指定报告输出目录
注意:⽇志⽂件和⽬录可以不存在,若为已经存在的情况下需要保证内容为空,否则会出现错误!
正确演⽰⽰例:

性能测试报告⽣成成功后,在test01⽂件夹下将出现以下内容:

双击index.html⽂件,界⾯展⽰如下:

八、测试总结
项目不足之处
1.用户体验问题
-
密码框功能不完善:缺少显示/隐藏密码功能,不利于复杂密码的输入验证
-
博客列表更新不便:从下往上更新的方式不便于用户查找最新内容
-
数据展示不准确:文章和分类数量仅为装饰性显示,未实现实际计算功能
2.界面设计问题
- 信息重叠混淆:详情页作者信息与个人信息位置重叠,导致用户身份辨识困难
- 布局不合理:个人信息区与文章作者信息缺乏明确区分
3.功能逻辑问题
- 写博客按钮功能异常:从首页点击写博客按钮后发布内容无法保存,直接跳转登录页
测试结论
测试通过情况
- 本次
BitNote博客系统测试基本通过,核心功能运行正常,但存在需要改进的细节问题。
改进建议
2.1 功能增强
- 实现分类统计功能:开发真实的文章分类和数量统计功能
- 优化博客发布流程:修复写博客按钮的功能逻辑
2.2 界面优化
重构详情页布局:
-
固定左侧个人信息区
-
将文章作者信息与发布时间并列显示
-
调整列表更新方式:改为从上往下更新,便于内容查找
2.3 体验提升
- 增加密码显示功能:提供密码可见性切换按钮
- 优化导航逻辑:确保各页面跳转逻辑一致且符合用户预期
更多推荐

所有评论(0)