一、项目背景
1.项目背景与意义
随着博客系统日常迭代频繁,涉及登录、列表展示、详情浏览、编辑发布等多页面交互场景。每次版本上线前,测试人员都需要手工验证核心业务流程,耗时耗力且容易遗漏边界场景。
为提升回归测试效率,本次项目引入 Selenium WebDriver 自动化测试框架,对博客系统核心功能进行 UI 自动化覆盖。通过自动化脚本替代重复性手工操作,实现:
- 核心流程一键回归:登录、列表、详情、编辑发布等主流程可全自动执行
- 异常场景自动验证:未登录拦截、弹窗提示、空密码校验等异常场景自动覆盖
- 可持续集成:后续版本迭代中可快速执行冒烟用例,提前发现前端交互缺陷
2.项目概述
本项目基于 Python + Selenium WebDriver 搭建自动化测试框架,针对博客系统的四大核心页面进行自动化测试覆盖:
|--------|----------|
| 页面 | 功能 |
| 登录页 | 用户登录认证 |
| 博客列表页 | 展示所有博客 |
| 博客详情页 | 查看单篇博客内容 |
| 博客编辑页 | 发布/修改博客 |
测试覆盖登录态 和未登录态两种场景,验证页面渲染、权限拦截、弹窗提示、数据提交等核心交互。
3. 已实现的主要功能
- 登录模块:支持正确账号密码登录;错误密码/空密码触发 Alert 弹窗提示
- 博客列表页:未登录访问自动弹窗跳转登录页;登录后展示个人信息、导航菜单、博客列表
- 博客详情页:登录用户可查看博客详细内容,可对博客进行编辑和删除操作
- 博客编辑页:支持标题+富文本正文编辑;登录态可正常发布,未登录态发布被拦截
4. 测试项目相关信息
系统测试地址:博客登陆页
自动化代码仓库:清逍/blog-auto-test
配套文档:《博客系统测试计划》、《产品需求文档》、《前端 UI 设计图》
测试技术栈:Python3 + Selenium4 + WebDriverWait 隐式等待 + ActionChains 富文本操作
二、测试安排
|--------|------------------------|------|----|------|------|------|--------------------------------------------------|
| 模块 | 子模块 | 提测时间 | 测试 | 工时 | 排期 | 进度 | 备注 |
| 用户登录模块 | 登录功能,未登录状态访问主页、写博客功能 | 7.12 | 博主 | 0.2d | 7.12 | 测试完成 | 正确登录成功,错误密码/空密码弹窗拦截正常 |
| 博客列表模块 | 未登录拦截,个人信息、导航菜单、博客列表展示 | 7.12 | 博主 | 0.2d | 7.12 | 测试完成 | 区分登录/未登录状态,校验页面展示和跳转逻辑 |
| 博客详情模块 | 查看博客详细内容,编辑博客、删除博客 | 7.13 | 博主 | 0.2d | 7.13 | 测试完成 | 登录用户可查看博客详细内容,可对博客进行编辑和删除操作 |
| 博客编辑模块 | 空内容校验、标题+富文本正文编辑、表单提交 | 7.13 | 博主 | 0.2d | 7.13 | 测试完成 | 覆盖登录/未登录两种状态,标题+富文本完整编辑流程验证 |
| 自动化回归 | 四大核心页面自动化脚本开发调试 | 7.13 | 博主 | 0.2d | 7.13 | 测试完成 | Python+Selenium框架搭建,封装通用工具类(Driver管理、Alert处理、截图) |
三、测试分类
(一)自动化功能测试
博客系统测试
博客系统自动化测试演示
1. 编写Web测试用例

登录页面详细完成用例

2. 搭建Python自动化项目
2.1 环境配置准备
- Python 3.12 环境安装,通过 pip 安装 selenium、webdriver-manager 依赖包;
- 使用 WebDriverManager 自动管理 Chrome 驱动版本,无需手动下载配置;
- 项目目录分层:common 公共工具层、cases 测试用例层,实现代码复用;
- 导入 Selenium 核心组件:WebDriverWait 隐式等待、ActionChains 键盘操作、By 元素定位。
2.2 封装公共工具类
python
import datetime
import os.path
import sys
import time
from selenium import webdriver
from selenium.common.exceptions import NoAlertPresentException
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
class Driver:
def __init__(self):
options = webdriver.ChromeOptions()
self.driver = webdriver.Chrome(service=Service(ChromeDriverManager().install()), options=options)
# 隐式等待 - 全局生效,创建浏览器对象时加一次就行
self.driver.implicitly_wait(10)
def getScreenshot(self):
dirname = datetime.datetime.now().strftime('%Y-%m-%d')
if not os.path.exists("../images/" + dirname):
os.makedirs("../images/" + dirname)
filename = sys._getframe().f_code.co_name + "-" + datetime.datetime.now().strftime(
"%Y-%m-%d-%H%M%S") + ".png"
self.driver.save_screenshot(f'../images/{dirname}/' + filename)
def HandleLoginAlert(self):
#弹窗不一定立刻出现,最好先等待一下然后进行处理,否则可能出现问题
time.sleep(1.5)
for _ in range(10):
try:
alert = self.driver.switch_to.alert
print("关闭弹窗:",alert.text)
alert.accept()
time.sleep(0.1)
except NoAlertPresentException:
break
# 公共获取用户名
def get_name(self):
return "zhangsan"
BlogDriver = Driver()
2.3 项目目录结构

此处仅放置博客登录页代码作为展示:
python
import time
from selenium.webdriver.common.by import By
from common.Utils import BlogDriver
class BlogLogin:
url = ""
driver = ""
def __init__(self):
self.url = "http://47.108.157.13:8090/blog_login.html"
self.driver = BlogDriver.driver
self.driver.get(self.url)
def TestLoginSuccess(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("zhangsan")
self.driver.find_element(By.CSS_SELECTOR, "#password").send_keys("123456")
time.sleep(1)
self.driver.find_element(By.CSS_SELECTOR, "#submit").click()
time.sleep(1)
self.driver.find_element(By.CSS_SELECTOR, "body > div.container > div.left > div > h3")
def TestLoginFail(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("zhangsan")
self.driver.find_element(By.CSS_SELECTOR, "#password").send_keys("111")
self.driver.find_element(By.CSS_SELECTOR, "#submit").click()
time.sleep(2)
BlogDriver.HandleLoginAlert()
# 错误的账号和正确的密码
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("heihei")
self.driver.find_element(By.CSS_SELECTOR, "#password").send_keys("123456")
self.driver.find_element(By.CSS_SELECTOR, "#submit").click()
time.sleep(2)
BlogDriver.HandleLoginAlert()
# 账号为空
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, "#submit").click()
time.sleep(2)
BlogDriver.HandleLoginAlert()
#密码为空
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, "#submit").click()
time.sleep(2)
BlogDriver.HandleLoginAlert()
所有模块测试用例通过 RunTest.py 批量执行
2.4 自动化测试执行过程中发现的业务缺陷
1.**博客登录页面性能缺陷:**在首次打开博客登录页面时,页面渲染速度极慢,需要等待数秒才能成功渲染完毕,进而支持操作。
2.博客列表页面弹窗缺陷:在未登录状态下访问博客列表页,会弹出弹窗提醒返回登录页面进行登录,问题出在此弹窗会出现两次,需要确认两次才可回到登录页面。
自动化执行结果:总用例 8 条,正常通过 8 条。
(二)性能测试
1. 模拟并发访问项目事务各页面
4 个接口,每个接口 150 样本



- 响应时间长,吞吐量小或相对稳定,可能系统达到了性能瓶颈
- 响应时间短,吞吐量大,性能越好
- 总样本 600 条,全部接口异常率 0%,无报错、无接口失败,功能可用性达标
通过观察线程响应图,发现最后有一个线程没有退出:

分析一下聚合列表推测核心原因:
- 博客列表接口查询耗时极长(最高 68 秒),该线程迟迟退出不了,因为没有得到相应

2. JMeter 150 并发压测报告总结
2.1 基础运行稳定性
- 本次压测总并发 150 线程,4 个接口(登录、博客列表页、博客详情页、博客添加)各 150 次请求,合计 600 次采样,请求错误率 0%,请求通过率 100%。
- 150 并发下服务未宕机、无业务报错,不存在并发锁、数据库崩溃、服务停机类致命故障,基础业务逻辑健壮。
- 少量博客列表页出现TruncatedChunkException数据截断异常,属于大数据包传输分片异常,虽未统计为业务失败,但反映大列表返回报文传输存在隐患。
2.2 各接口性能瓶颈拆解(核心指标对照)
1. 博客列表页(系统最严重瓶颈)
- 响应耗时极差:平均 20691.21ms(约 21 秒),最大 75342ms(近 75 秒),99 分位高达 73339.23ms;
- APDEX 仅 0.02,远低于合格标准(0.75),几乎全部用户体验极差;
- 吞吐量仅 1.84 req/s,但单次返回数据量巨大,出现报文截断报错;
- 问题根源:未做分页全量查询,一次性拉取海量数据,数据库查询 + 报文传输双重耗时,并发越高响应延迟膨胀越严重,完全无法满足正常用户访问。
2. 博客详情页
- 平均响应 11842.59ms(约 11.8 秒),99 分位 30007.03ms(30 秒);
- APDEX 0.15,用户体验极差;
- 吞吐量仅 1.84 req/s,查询效率低下,大概率存在无索引、循环查询、无缓存问题。
3. 登录接口
- 平均响应 5652.65ms(5.6 秒),99 分位 20368.36ms(20 秒);
- APDEX 0.22,大量用户等待超时感明显;
- 吞吐量 4.79 req/s,登录校验逻辑 / 数据库查询存在性能损耗。
4. 博客添加(唯一性能合格接口)
- 平均响应仅 54.53ms,最大 351ms,99 分位 346.41ms,全部请求耗时低于 1 秒;
- APDEX 达到 1.0,完全满足体验标准;
- 吞吐量 1.99 req/s,写入操作本身逻辑简单,无大量数据查询,性能表现最优。
2.3 系统整体性能问题
1. 整体吞吐能力薄弱: 4 个接口合计总吞吐量仅 7.34 req/s,系统承载并发能力极差,少量用户同时访问就会出现长时间页面加载。
2. 负载越高性能衰减越明显: 150 并发稳定运行时,博客列表页延迟持续走高,说明存在累积型性能损耗:数据库查询缺少索引、热点数据无内存缓存、存在 N+1 循环查询等底层问题。
3. 高并发扩容风险: 当前仅 150 并发就出现数十秒级响应延迟、大数据报文截断异常,若直接将并发提升至 200,会出现大面积请求超时、服务响应雪崩,无法支撑更大访问量。
**4. 用户体验整体崩盘:**全局 APDEX 仅 0.347,低于 0.5 的容忍阈值,除新增接口外,其余核心页面(列表、详情、登录)均无法满足 500ms、1500ms 的体验标准,用户等待感极强。
四、遗留风险
1. 博客列表接口存在致命性能瓶颈: 150 并发下平均响应 27 秒、最大近 75 秒,存在TruncatedChunkException大数据包截断报错;接口未实现分页、无热点数据缓存,数据库全量查询导致并发越高加载延迟越严重,线上流量高峰期极易出现页面加载超时、数据传输失败。
2. 前端页面交互缺陷未修复: 未登录访问列表页会重复弹出登录拦截弹窗,需多次确认才能跳转;登录页面首次渲染缓慢,自动化执行时易因页面未加载完成引发脚本不稳定。
3. 自动化测试体系不完善: 脚本强依赖页面 DOM 元素结构,前端改版后需大量修改定位代码;未配置定时 CI 自动执行,版本迭代回归只能手动启动脚本,测试维护、冒烟回归效率偏低。
**4. 本次性能测试覆盖范围存在局限性:**本轮仅完成 150 并发梯度压力测试,受本次测试周期与资源限制,暂未开展 200 以上极限并发压测、长时间稳定性耐久测试,暂未验证系统持续高负载场景下内存泄漏、连接池耗尽等潜在隐患,后续迭代阶段可补充该两类测试完善性能评估。
五、测试结果评估
1. 基础业务功能可用,低流量环境可临时上线: 自动化 8 条核心用例全部通过,150 并发压测整体错误率 0%,无服务宕机、数据库崩溃、并发锁死等阻断性故障,单用户、少量用户访问流程可正常使用。
2. 自动化脚本完成核心流程覆盖,但执行稳定性一般 :脚本覆盖登录、列表、详情、编辑发布全业务链路,可用于迭代版本冒烟回归;但受页面渲染慢、重复弹窗缺陷影响,执行过程偶发等待超时、弹窗处理异常,需优化等待策略、封装更强的弹窗兼容逻辑。
3. 系统并发承载能力薄弱,高流量场景用户体验极差: 博客列表是系统核心短板,全局 APDEX 仅 0.347 远低于体验合格线,登录、详情页面 99 分位响应达到 20~30 秒,少量用户同时访问就会出现长时间页面加载,流量高峰会引发大面积卡顿、报文传输报错。
**4. 上线前优化优先级明确,后续需补充全链路测试:**上线前优先完成博客列表分页改造、数据库查询索引优化、Redis 热点缓存、接口报文压缩,同步修复前端重复弹窗、页面慢渲染问题;待性能优化完成后,补充极限并发压测、长时间稳定性测试,并搭建 CI 自动化定时回归流水线。